MySQLの「WITH」句


98

MySQLを使用して "WITH"句でビューを作成しようとしています

WITH authorRating(aname, rating) AS
   SELECT aname, AVG(quantity)
   FROM book
   GROUP BY aname

しかし、MySQLがこれをサポートしているようには見えません。

これはかなり標準的なものだと思いましたが、Oracleがこれをサポートしていると確信しています。MySQLに強制的に「WITH」節を使用させる方法はありますか?MyISAMとinnoDBエンジンで試してみました。これらはどちらも機能しません。

回答:


109

更新:MySQL 8.0は、再帰CTEを含む一般的なテーブル式の機能をついに取得します。

これを発表したブログは次のとおりです。http//mysqlserverteam.com/mysql-8-0-labs-recursive-common-table-expressions-in-mysql-ctes/

以下は私の以前の回答で、私が最初に2008年に書いたものです。


MySQL 5.xはWITH、SQL-99で定義された構文を使用するクエリをサポートしません。これは、共通テーブル式とも呼ばれます

これは、2006年1月以降のMySQLの機能リクエストでした。http://bugs.mysql.com/bug.php?id = 16244

共通テーブル式をサポートする他のRDBMS製品:


1
SQLiteは、2014-02-03にリリースされたバージョン3.8.3以降のWITH句をサポートしています。
Martijn 14

H2とFirebirdをリストに追加しました。
a_horse_with_no_name 2014

2
@BillKarwin:私は、MySQLがこれまでに実施するとは考えていない任意の近代的なDBMSの機能(チェック制約、ウィンドウ関数、式のインデックス、部分インデックス、繰延制約を...)。
a_horse_with_no_name 2014

2
@a_horse_with_no_name、スケーラビリティをはるかに優先するようです。彼らは、現代のハードウェアを利用するために、内部をよりスケーラブルにすることに長い間焦点を合わせてきました。しかし、私は彼らがSQL機能を無視していると思います。
ビルカーウィン2014

1
@BlakeMcBride、あなたは間違っている、あなたのコメントはFUDであり、実際には根拠がない。オラクルは、Oracle DBがうまく機能しない他のデータベース製品も所有しています。例:TimesTen、BerkeleyDB。彼らは市場を拡大するためにそれらのデータベースを取得しました。MySQLはWebアプリケーション市場で支配的であり、Oracle DBはそうではないため、MySQLを買収しました。OracleがMySQLを試してみるのは意味がありません。4月の会議でOracle MySQL開発者と話しました。実際、彼らはMySQLのWITHの実装に取り​​組んでいます。
ビルカーウィン2016

17

あなたはこのようなsomethinkgに興味があるかもしれません:

select * from (
    select * from table
) as Subquery

サブクエリについて説明していただけますか?select * from((select * from table1)UNION ALL(select * from table2))Group by some?

1
@Kathyこんにちは、Subquery派生テーブル自体に使用した名前です。使用するfrom ( ... )と、一時テーブル(派生テーブル)のようなものを作成し、名前が必要になります。それが私が使用しas Subqueryた理由です。はい、できますが、外部の派生テーブル(の直前Group By)に名前を付ける必要があります。お役に立てば幸いです。
モスティモスタチョ

@MostyMostachoこんにちは、ここで少しスプーンで食べてください。MySQLに変換するのに苦労しています。ご覧になれますか?多分ここに私の質問をリンクまたは回答しますか?リンク
プラナフ2015

13

あなたは正しい構文を持っています:

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のロードマップを見るとよいでしょう。この機能がいつサポートされるかは完全にはわかりませんが、読みやすいロールアップクエリを作成するのに最適です。


9

OracleはWITHをサポートしています。

このようになります。

WITH emps as (SELECT * FROM Employees)
SELECT * FROM emps WHERE ID < 20
UNION ALL
SELECT * FROM emps where Sex = 'F'

@ysth WITHは一般的に検索から除外される一般的な単語であるため、グーグルで検索するのは困難です。

SELECTドキュメントを見て、サブクエリファクタリングがどのように機能するかを確認する必要があります。

これはOPに応答しないことはわかっていますが、混乱が始まった可能性がある場合は、クリーンアップしています。


とにかく私の混乱を片付けませんでした。WITH句はありませんが、WITHステートメントはありますか?
ysth

1
ああ、なるほど。選択の前にあるのは、選択の句です。CREATE VIEWでも使用できますか?サブセレクトに参加するのとどう違うのですか?WITHの後の名前にパラメータがある例がオンラインで表示されません-それらはどのように機能しますか?
ys、2008年

1
それは非常に異なります。同じsubqryを2回使用することに注意してください。2回定義する必要はありません。もちろん、同じクエリをコピーして貼り付けることもできますが、これは簡単な例です。WITH句がページに続き、メインクエリで4回使用されたと想像してください。あなたはそれを感謝します。

構文を説明するドキュメントにリンクしました。ビューの限り。確かにそこで機能します。

3

@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句に変換することができます。




0

一時テーブルを試したことはありますか?これは私の支配を解決しました:

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 ...;

1
私は注意する必要があります:stackoverflow.com/questions/343402/…テーブルを2度開くことはできません:-(

テーブル内の小さなデータセットに対する私のソリューション:abcのようなテーブルabc2を作成します。abc2に挿入* select abc;
2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.