In MSSQL, I have a query something like:
WITH temp AS (
SELECT
*
FROM
xx.xxxx
)
But WITH temp AS () isn't supported in MySQL syntax, I wonder what the equivalent syntax should be in MySQL Workbench? Thanks.
Below is a screenshot of the syntax error:
If you have MySQL 5.x and you need to adapt the query which contains CTE, then convert
WITH cte AS (cte query text)
SELECT ...
FROM cte
...
to
SELECT ...
FROM (cte query text) cte
...
If there is more than one CTE then perform this substitution with accuracy from latter CTE to former one (you may need to use multiple copies of some CTE subquery text - this is a norma).
Related
Such as this :
Select * From (
WITH RECURSIVE cte_name AS (
initial_query -- anchor member
UNION ALL
recursive_query -- recursive member that references to the CTE name
)
SELECT * FROM cte_name
) A
Section 13.2.13 of the MySql 8.0 reference manual that handles WITH syntax for Common Table Expressions, mentions the following :
A WITH clause is permitted in these contexts:
At the beginning of subqueries (including derived table subqueries):
SELECT ... WHERE id IN (WITH ... SELECT ...) ...
SELECT * FROM (WITH ... SELECT ...) AS dt ...
So, that clarifies my question, therefore putting my own answer as a community wiki.
When I use MySQL, the following query runs clean.
SELECT 1 as num1, (select(num1 + 1)) as num2
But PostgreSQL is returning an error.
ERROR: column "num1" does not exist
Why is it responding differently?
The question shouldn't be why does Postgres not support this syntax, but why MySQL does. In most RDBMSs, aliases are only resolved after the query is executed, so you can't use them from within the query that declares them. E.g., the more common usecase - you cannot use a column alias in a where clause of the query/table-element that declared it.
One way around this is to use subqueries:
SELECT num1, num1 + 1 AS num2
FROM (SELECT 1 AS num1) t
you should use PostgreSQL syntax , because PgSql does not support sub query this way, try this
WITH tblcontent AS (SELECT 1 as num1)
SELECT num1, num1 + 1 AS num2 from tblcontent
I can't find any good source, but I am quite sure that the standard does not require aliases of projected columns to be visible inside a correlated sub query. I just tried it in SQL Server and Oracle, and both of them seem to agree with PostgreSQL here, rejecting using x in a correlated sub query, no matter in which clause of the outer select it is located.
It is similar to how MySQL allows the following query:
SELECT a + 1 x
FROM t
ORDER BY x + 1
but SQL Server and Postgres do not. MySQL seems to be more permissive with regard to using aliases in various clauses than the standard requires.
Is there a way to use window functions in MySQL queries dynamically within a SELECT query itself? (I know for a fact that it is possible in PostgreSQL).
For example, here is the equivalent query in PostgreSQL:
SELECT c_server_ip, c_client_ip, sum(a_num_bytes_sent) OVER
(PARTITION BY c_server_ip) FROM network_table;
However, what would be the corresponding query in MySQL?
Starting MySQL 8.0, you can now use OVER and partition, so consider upgrading to the latest version :)
Hope this might work:
select A.c_server_ip, A.c_client_ip, B.mySum
from network_table A, (
select c_server_ip, sum(a_num_bytes_sent) as mySum
from network_table group by c_server_ip
) as B
where A.c_server_ip=B.c_server_ip;
I have a problem with Aliased Columns in MySQL!
My Query:
SELECT Price AS Pr, (Pr*10/100) FROM MyTable;
MySQL WorkBench Error: UnKnown Column 'Pr' in Field List !!!
I tested my query in W3Schools with no error !
I tested my query in W3Schools with no error!
This doesn't prove that your query is valid.
You can only use aliases in GROUP BY, ORDER BY or HAVING clauses. Your usage variant is not allowed, because the value of alias is not known when MySQL is selecting the 2-nd column.
I've got a suspicion that W3Schools uses MS Access to run user queries, and MS Access does allow such atrocity as referencing column aliases in a SELECT clause that are defined in the same SELECT clause.
The standard doesn't allow this and MySQL does follow standard in this particular case.
As for solution to your problem, I can see two options.
The more generic solution, which would run in probably any SQL product, would be to use a derived table:
SELECT
Pr,
(Pr * 10 / 100) AS SomethingElse
FROM
(
SELECT
SomeComplexExpression AS Pr
FROM MyTable
) AS sub
;
The other option would be to use a variable, which is MySQL-specific:
SELECT
#Pr := SomeComplexExpression AS Pr,
(#Pr * 10 / 100) AS SomethingElse
FROM MyTable
;
Finally, if you need to test/demonstrate if something can/cannot work in MySQL, I'd recommend using SQL Fiddle.
I'm trying to use MySQL to create a view with the "WITH" clause
WITH authorRating(aname, rating) AS
SELECT aname, AVG(quantity)
FROM book
GROUP BY aname
But it doesn't seem like MySQL supports this.
I thought this was pretty standard and I'm sure Oracle supports this. Is there anyway to force MySQL to use the "WITH" clause? I've tried it with the MyISAM and innoDB engine. Both of these don't work.
Update: MySQL 8.0 is finally getting the feature of common table expressions, including recursive CTEs.
Here's a blog announcing it: http://mysqlserverteam.com/mysql-8-0-labs-recursive-common-table-expressions-in-mysql-ctes/
Below is my earlier answer, which I originally wrote in 2008.
MySQL 5.x does not support queries using the WITH syntax defined in SQL-99, also called Common Table Expressions.
This has been a feature request for MySQL since January 2006: http://bugs.mysql.com/bug.php?id=16244
Other RDBMS products that support common table expressions:
Oracle 9i release 2 and later:
http://www.oracle-base.com/articles/misc/with-clause.php
Microsoft SQL Server 2005 and later:
http://msdn.microsoft.com/en-us/library/ms190766(v=sql.90).aspx
IBM DB2 UDB 8 and later:
http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/admin/r0000879.htm
PostgreSQL 8.4 and later:
https://www.postgresql.org/docs/current/static/queries-with.html
Sybase 11 and later:
http://dcx.sybase.com/1100/en/dbusage_en11/commontblexpr-s-5414852.html
SQLite 3.8.3 and later:
http://sqlite.org/lang_with.html
HSQLDB:
http://hsqldb.org/doc/guide/dataaccess-chapt.html#dac_with_clause
Firebird 2.1 and later (the first Open Source DBMS to support recursive queries):
http://www.firebirdsql.org/file/documentation/release_notes/html/rlsnotes210.html#rnfb210-cte
H2 Database (but only recursive):
http://www.h2database.com/html/advanced.html#recursive_queries
Informix 14.10 and later:
https://www.ibm.com/support/knowledgecenter/SSGU8G_14.1.0/com.ibm.sqls.doc/ids_sqs_with.htm
You might be interested in something like this:
select * from (
select * from table
) as Subquery
You've got the syntax right:
WITH AuthorRating(AuthorName, AuthorRating) AS
SELECT aname AS AuthorName,
AVG(quantity) AS AuthorRating
FROM Book
GROUP By Book.aname
However, as others have mentioned, MySQL does not support this command. WITH was added in SQL:1999; the newest version of the SQL standard is SQL:2008. You can find some more information about databases that support SQL:1999's various features on Wikipedia.
MySQL has traditionally lagged a bit in support for the SQL standard, whereas commercial databases like Oracle, SQL Server (recently), and DB2 have followed them a bit more closely. PostgreSQL is typically pretty standards compliant as well.
You may want to look at MySQL's roadmap; I'm not completely sure when this feature might be supported, but it's great for creating readable roll-up queries.
Oracle does support WITH.
It would look like this.
WITH emps as (SELECT * FROM Employees)
SELECT * FROM emps WHERE ID < 20
UNION ALL
SELECT * FROM emps where Sex = 'F'
#ysth WITH is hard to google because it's a common word typically excluded from searches.
You'd want to look at the SELECT docs to see how subquery factoring works.
I know this doesn't answer the OP but I'm cleaning up any confusion ysth may have started.
Building on the answer from #Mosty Mostacho, here's how you might do something equivalent in MySQL,for a specific case of determining what entries don't exist in a table, and are not in any other database.
select col1 from (
select 'value1' as col1 union
select 'value2' as col1 union
select 'value3' as col1
) as subquery
left join mytable as mytable.mycol = col1
where mytable.mycol is null
order by col1
You may want to use a text editor with macro capabilities to convert a list of values to the quoted select union clause.
MariaDB is now supporting WITH. MySQL for now is not.
https://mariadb.com/kb/en/mariadb/with/
Have you ever tried Temporary Table?
This solved my convern:
create temporary table abc (
column1 varchar(255)
column2 decimal
);
insert into abc
select ...
or otherwise
insert into abc
values ('text', 5.5), ('text2', 0815.8);
Then you can use this table in every select in this session:
select * from abc inner join users on ...;
WITH authorRating as (select aname, rating from book)
SELECT aname, AVG(quantity)
FROM authorRating
GROUP BY aname