MySQLにOracleのWITH句に相当するものはありますか?
存在しない。開発しない限り(MySQLはオープンソースであり、誰でも貢献できます。)
ANSI/ISO SQL WITH
キーワードは、共通テーブル式(CTE)を定義するために使用され、1つまたは複数のネストされた参照を持つ複雑なクエリを簡素化します。 Oracle、Postgres、SQL-Server、DB2で利用できますが、MySQLでは利用できません。
最後のクエリには、共通テーブル式のいずれかへの参照が(通常はFROM
句にありますが、他の部分にある可能性があります)、1回以上ある場合があります。クエリはMySQLで派生テーブルを使用して(CTEなしで)作成できますが、参照は繰り返し行う必要があります。
50代と7月に生まれたすべての人と、同じ年に生まれたすべての人の数を示す愚かなクエリの例:
WITH a AS
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
)
, b AS
( SELECT birthyear, COUNT(*) AS cnt
FROM a
GROUP BY birthyear
)
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM a JOIN b
ON a.birthyear = b.birthyear
WHERE MONTH(a.birthdate) = 7 ;
MySQLでは、次のように記述できます。
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
) AS a
JOIN
( SELECT birthyear, COUNT(*) AS cnt
FROM
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
) AS aa
GROUP BY birthyear
) AS b
ON a.birthyear = b.birthyear
WHERE MONTH(a.birthdate) = 7 ;
派生テーブルa
のコードが重複していることに注意してください。より複雑なクエリでは、コードを複数回記述する必要があります。
それは機能しますが、WITH句を使用する利点を提供しないのは残念です。つまり、同じクエリを数回実行しないことです(複雑なクエリは、かなり遅くなり、データベースエンジンに非常に負荷がかかる可能性があります。私は苦労しました)。 。
元のWITH句で定義された各SELECTを独自の一時テーブルに挿入し、クエリ内で使用することをお勧めします。 MySQLでは、ユーザーセッションが終了すると一時テーブルが自動的に削除されます。
編集:
MySQLでの3つの回避策を明確に公開している同様のスレッドでこの答えを見ました:
https://stackoverflow.com/a/1382618/290629
MySQLプロシージャの例は、セッションを続行してそれらのリソースを解放したい場合に備えて、一時テーブルを作成および削除します(私はそれを使用します)構文の例として): https://stackoverflow.com/a/5553145/290629