Предложение "С" MySQL
Я пытаюсь использовать MySQL для создания представления с предложением WITH
WITH authorRating(aname, rating) AS
SELECT aname, AVG(quantity)
FROM book
GROUP BY aname
Но, похоже, MySQL не поддерживает это.
Я думал, что это довольно стандартно, и я уверен, что Oracle поддерживает это. Есть ли способ заставить MySQL использовать предложение WITH? Я пробовал это с MyISAM и движком innoDB. Оба из них не работают.
7 ответов
Обновление: MySQL 8.0 наконец-то получил возможность использовать общие табличные выражения, включая рекурсивные CTE.
Вот блог, объявляющий об этом: http://mysqlserverteam.com/mysql-8-0-labs-recursive-common-table-expressions-in-mysql-ctes/
Ниже мой предыдущий ответ, который я первоначально написал в 2008 году.
MySQL не поддерживает запросы с использованием WITH
синтаксис, определенный в SQL-99, также называется общими табличными выражениями.
Это был запрос функции для MySQL с января 2006 года: http://bugs.mysql.com/bug.php?id=16244
Другие продукты RDBMS, которые поддерживают общие табличные выражения:
- Oracle 9i, выпуск 2 и более поздние версии:
http://www.oracle-base.com/articles/misc/with-clause.php - Microsoft SQL Server 2005 и более поздние версии:
http://msdn.microsoft.com/en-us/library/ms190766(v=sql.90).aspx - IBM DB2 UDB 8 и более поздние версии:
http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/admin/r0000879.htm - PostgreSQL 8.4 и более поздние версии:
https://www.postgresql.org/docs/current/static/queries-with.html - Sybase 11 и позже:
http://dcx.sybase.com/1100/en/dbusage_en11/commontblexpr-s-5414852.html - SQLite 3.8.3 и более поздние версии:
http://sqlite.org/lang_with.html - HSQLDB:
http://hsqldb.org/doc/guide/dataaccess-chapt.html - Firebird 2.1 и более поздние версии (первая СУБД с открытым исходным кодом, поддерживающая рекурсивные запросы): http://www.firebirdsql.org/file/documentation/release_notes/html/rlsnotes210.html
- База данных H2 (но только рекурсивная):
http://www.h2database.com/html/advanced.html
Другие базы данных, в которых отсутствует поддержка предложения WITH (по состоянию на февраль 2014 года):
- Informix (хотя Informix поддерживает
CONNECT BY
синтаксис, который когда-то использовался Oracle)
http://pic.dhe.ibm.com/infocenter/idshelp/v115/index.jsp?topic=%2Fcom.ibm.sqls.doc%2Fids_sqs_2033.htm
Вас может заинтересовать что-то вроде этого:
select * from (
select * from table
) as Subquery
Вы правильно поняли синтаксис:
WITH AuthorRating(AuthorName, AuthorRating) AS
SELECT aname AS AuthorName,
AVG(quantity) AS AuthorRating
FROM Book
GROUP By Book.aname
Однако, как уже упоминалось, MySQL не поддерживает эту команду. WITH был добавлен в SQL:1999; самая новая версия стандарта SQL - SQL:2008. Вы можете найти дополнительную информацию о базах данных, которые поддерживают различные функции SQL: 1999, в Википедии.
MySQL традиционно немного отстает в поддержке стандарта SQL, тогда как коммерческие базы данных, такие как Oracle, SQL Server (в последнее время) и DB2, следуют им чуть более внимательно. PostgreSQL, как правило, также достаточно совместим со стандартами.
Вы можете посмотреть на дорожную карту MySQL; Я не совсем уверен, когда эта функция может поддерживаться, но она отлично подходит для создания читаемых сводных запросов.
Oracle поддерживает СО.
Это будет выглядеть так
WITH emps as (SELECT * FROM Employees)
SELECT * FROM emps WHERE ID < 20
UNION ALL
SELECT * FROM emps where Sex = 'F'
@ysth WITH трудно гуглить, потому что это обычное слово, обычно исключаемое из поисков.
Вы хотели бы взглянуть на документы SELECT, чтобы увидеть, как работает факторинг подзапроса.
Я знаю, что это не отвечает ОП, но я убираю все беспорядки, которые могли начаться.
Основываясь на ответе @Mosty Mostacho, вот как вы можете сделать что-то эквивалентное в MySQL для конкретного случая определения того, какие записи не существуют в таблице и отсутствуют в любой другой базе данных.
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
Возможно, вы захотите использовать текстовый редактор с возможностями макросов для преобразования списка значений в предложение select union в кавычках.
MariaDB теперь поддерживает WITH. MySQL на данный момент нет. https://mariadb.com/kb/en/mariadb/with/
WITH authorRating as (select aname, rating from book)
SELECT aname, AVG(quantity)
FROM authorRating
GROUP BY aname
Вы когда-нибудь пробовали Temporary Table? Это решило мое превращение:
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);
Затем вы можете использовать эту таблицу для каждого выбора в этой сессии:
select * from abc inner join users on ...;