I must make an exponentiation of a number and I don't know which function to use between POW() and POWER(). Which of the two functions is better?
Looking at the MySQL documentation I saw that they are synonymous, but I wanted to understand if there was a reason for two functions that do the same thing.
POWER is the synonym of POW. So nothing is better, it is the same:
POWER(X,Y)
This is a synonym for POW().
Using two different names for the same function gives you the possibility to port an SQL query from one dialect to an other dialect without (big) changes.
An example:
You want to use the following TSQL query on MySQL too:
SELECT POWER(2,2) -- 4
Now you can write these query specific for the dialects:
SELECT POWER(2,2) -- 4 - TSQL (POW is not available on TSQL)
SELECT POW(2,2) -- 4 - MySQL
But you can also use the POWER function on MySQL since this is a synonym for POW:
SELECT POWER(2,2) -- 4 - TSQL and MySQL
pow and power are synonyms in MySQL.
I'd use power since it's part of the ANSI SQL standard and using it would make your code easier to port if you ever decide to use a different database.
Related
Of course, we do our job before and searched this community or the web for similar posts but we found nothing.
Issue:
We are not happy with our current hosting provider and have to make change. In the middle of our database switch from MySQL 5.7 to MariaDB 10.3, we have recognized a SET handling difference, which works perfect in MySQL.
SQL code:
SET #sb = 0;
SELECT art,sb
FROM ARTICLE
WHERE(#sb:=sb) > 700 AND #sb <= 1000 >AND art = 'AM';
MySQL result:
art
sb
AM
900.00
AM
960.00
AM
1000.00
AM
770.00
AM
800.00
the list is much longer...
MariaDB result:
art
sb
AM
770.00
AM
960.00
AM
1200.00
AM
3000.00
only 10 rows...
In fact there is a difference between them.
But we want to know:
Can we configure this in MariaDB, that we get the same result in MySQL?
Should we replace the Set handling in MariaDB with another one?
No, this is not possible.
In fact, the MySQL documentation warns about the use of variable assignments inside SQL statements:
The order of evaluation for expressions involving user variables is undefined. For example, there is no guarantee that SELECT #a, #a:=#a+1 evaluates #a first and then performs the assignment.
What's more, this is a "feature" that is subject to removal:
Previous releases of MySQL made it possible to assign a value to a user variable in statements other than SET. This functionality is supported in MySQL 8.0 for backward compatibility but is subject to removal in a future release of MySQL.
So you should not rely on that, and rewrite your queries.
The MySQL documentation is quite clear on this point:
As a general rule, other than in SET statements, you should never assign a value to a user variable and read the value within the same statement.
That your code ever worked was something of a coincidence. The reason for such warnings is that behavior may change between releases; or even that the results may be inconsistent between runs on the same database.
You should replace the variables with window functions. The exact function is a bit unclear. Sample data, desired results, and a clear explanation of the results always helps.
I am attempting to create several calculated columns in a table with different parts of a parsed filename. Using the InstrRev function is critical to isolate the base file name or extension, but InstrRev is not supported in calculated columns.
I know that there are other ways to solve my problem that don't use calculated columns, but does anyone have a valid calculated column formula that could help me?
Access lets you use VBA functions (including user-defined functions) directly from within a SQL query - however they only work within an Access context - if you have another frontend for a JET (now ACE) database - or inside a computed/calculated column, they won't work - as you've just discovered.
Unfortunately Access (JET and ACE) have only a very meagre and anaemic selection of built-in functions, and the platform has now lagged-behind SQL Server (and even the open-source SQLite) significantly - Access 2016 has not made significant changes to its SQL implementation since Access 2000 (16 years of stagnation!) whereas SQL Server 2016's T-SQL language is so evolved it's almost unrecognizable compared to SQL Server 2000.
JET and ACE support the standard ODBC functions ( https://msdn.microsoft.com/en-us/library/bb208907(v=office.12).aspx ) however none of these perform a "reverse index-of" operation. Also absent is any form of pattern-matching function - though the LIKE operator works, it only returns a boolean result, not a character index.
In short: what you want to do is impossible.
This has been discovered by many people before you:
https://social.msdn.microsoft.com/Forums/office/en-US/6cf82b1b-8e74-4ac8-9997-61cad8bb9310/access-database-engine-incompatible-with-instrrev?forum=accessdev
He maintains a list of DAO/Jet/etc reserved words - and on that list you will see the InstrRev is a VBA() function, and is not a part of the Jet/Ace Engines.
using InStrRev() and similar functions in Jet/ACE queries outside of Access
As you have discovered, SQL queries executed from within Access can use many VBA functions that are not natively supported by the Jet/ACE dialect of SQL
That said, computed/calculated columns are only really of use in stored VIEW objects ("Queries" objects in Access parlance) - which in turn are used for user convenience, not for any programming advantage - especially as these are scalar functions that are evaluated for every row of data that the engine processes (making them potentially very expensive and inefficient to run).
...so the only real solution is to abandon computed/calculated columns and perform this processing in your own application code - but the advantage is that your program will likely be significantly faster.
...or don't use Access and switch to a different DBMS with better active support, such as SQLite (for an in-process database), SQL Server (now with LocalDb for in-process support), or VistaDB (proprietary, but 100% Managed code). Note that Access also supports acting as a front-end for a SQL Server "backend" data-store - where you could create a VIEW that performs this operation, then query the view from your Access code or other consuming client.
There is a workaround if you must: Create a duplicate column that contains the string-reversed value of your original column, then you can evaluate the ODBC LOCATE or JET SQL InStr functions on it and get the result you want (albiet, reversed) - but this would require double the storage space.
e.g.
RowId, FileName , FileNameRev
1 , 'Foo.txt', 'txt.ooF'
2 , 'Bar.txt', 'txt.raB'
Avoid any calculated field. It's a "super user" feature only, that will cause you nothing but trouble. Calculated fields - or expressions - belong in a query.
So create a simple select query:
Select
*,
InStrRev([FieldToCheck], "YourMatchingString") As StringMatch
From
YourTable
Save the query, and then use this whenever you need the table values and this expression.
I would like to know if there is a generic SQL equivalent to Oracle's hierarchical syntax start with...connect by. I need something which can be used on any database. Here is the sort of query I mean (using Oracle's example EMP table):
SELECT empno , ename , job , mgr ,hiredate ,level
FROM emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr.
Recursive Common Table Expressions work for many database implementations but not for MySQL.
There is no way of doing this in MySQL. There are some nasty hacks listed in an article by Mike Hillyer which could be used in other databases as well. But using something as inelegant as the Nested Set model in Oracle just so the same code will run on MySQL seems perverse.
The generic way would be CTE, as they are specified in SQL-99, and most flavours of RDBMS support it (even Oracle added recursiveness to its CTEs in 11gR2). The lack of support for CTE in MySQL was raised as a bug in 2006. Perhaps now Oracle owns MySQL they will get around to implementing it.
However, it really depends on your business reasons for wanting a generic solution and which database versions you really need to cover. It is a truism of writing database applications which can run on any RDBMS that they run well on none of them.
I am working in a project where we are using SQL Server database currently. But recently a decision has been taken that the database will be changed to MySQL.
I am not using any stored procedures, views, triggers, user defined functions, etc. But I think even then some queries written for SQL Server will not be supported by MySQL.
Can anyone help: what are the things that I have to check (and change) so that all the queries will work properly for MySQL also?
Queries that I know without consulting the documentation that will not work:
(recursive) common table expressions
windowing functions
queries using the standard SQL string concatenation ||
UPDATEs with JOIN are different between the two systems
Date arithmetics: date_column + 1 behaves differently in SQL Server
Division by zero will produce an error
SQL Server will reject values that do not fit into a column (instead of silently truncating it, which MySQL does in the default installation)
DDL that will not work and might have an impact on performance and/or data quality
datetime columns where you need precision up to milliseconds
tables with check constraints
indexed views
triggers on views
table functions (select * from my_function(42);)
filtered indexes ("partial index")
function based indexes
There's always the option to take commercial support from MySQL AB for this problem. I'm pretty sure they've done enough MSSQL->MySQL migrations to know alot about that. If a price tag on the migration is not a problem.
Alternatively, you could try to run the MySQL Migration Toolkit over the data and look for meaningful error messages at the stuff it cannot migrate. MySQL Migration Toolkit is part of the MySQL GUI Tools.
I am deploying a Ruby on Rails application that I developed with Sqlite3 to a server with either MySQL or PostgreSQL. I quickly discovered that the "group by" and "strftime" functions that I am using heavily to produce by-month rollup reports are working differently or not compatible between the various databases.
I can refactor my code to do the grouping, summing and averaging - but the database does such a nice job of it and reduces the processing required by the server! Advanced applications go beyond simple select and join. ActiveRecord gives us :group, but the DATABASES are not CONSISTENT.
So my question is a matter of architecture - does anyone expect to create truly "database portable" applications in Ruby on Rails? Should I modify my codebase to work with MySQL only and forget about the other databases? Should I modify my codebase to do the advanced grouping, summing, and averaging?
cheers - Don
Several comments:
Develop and test with the same RDBMS brand and version that you're going to deploy to.
Writing portable SQL code is hard because vendors have all these non-standard extra functions and features. For example, strftime() is not part of the ANSI SQL standard. The only way to resolve this is to RTM for each database you use, and learn what functions they have in common. Sometimes they have a function of a different name that you can use in a similar way. There's no short-cut around this -- you have to study the manuals.
All the databases support GROUP BY, but SQLite and MySQL are kind of more permissive about certain usage than standard ANSI SQL (and all other brands of database which do follow the standard). Specifically, in your GROUP BY clause you must name every column in your select-list that isn't part of a grouping function.
The following two examples are right:
SELECT A, B, COUNT(C) FROM MyTable GROUP BY A, B;
SELECT A, COUNT(C) FROM MyTable GROUP BY A;
But the next one is wrong, because B has multiple values per group, and it's ambiguous which value it should return in a given row:
SELECT A, B, COUNT(C) FROM MyTable GROUP BY A;
No framework writes truly portable SQL. Rails' ActiveRecord solves this only in very trivial cases. In fact, ActiveRecord helps solve neither of the examples you give, of functions that are brand-specific, and non-standard GROUP BY clauses.
The problem is that especially with GROUP BY MySQL does it wrong. If you leave out columns from the group by MySQL simply returns "something" accepting that the results may be indeterminate.
You can (should) use the ONLY_FULL_GROUP_BY parameter to make MySQL throw an error if the result of your GROUP BY would not be clearly defined.
Actually there are a lot more settings that should be changed in MySQL to make it behave more sanely
You might be interested in reading this:
http://www.slideshare.net/ronaldbradford/mysql-idiosyncrasies-that-bite-201007