Gibt es eine MySQL-Entsprechung der WITH-Klausel in Oracle?
Da ist nicht. Sofern (bis) man es entwickelt (MySQL ist Open Source, jeder kann dazu beitragen.)
Das WITH
Schlüsselwort ANSI / ISO SQL wird zum Definieren von Common Table Expressions (CTEs) verwendet und vereinfacht komplexe Abfragen mit einer oder mehreren verschachtelten Referenzen. Es ist in Oracle, Postgres, SQL-Server, DB2, aber nicht in MySQL verfügbar.
Die letzte Abfrage kann Verweise enthalten (normalerweise in der FROM
Klausel, sie können sich jedoch auch in einem anderen Teil befinden) auf einen oder mehrere der allgemeinen Tabellenausdrücke enthalten. Die Abfrage kann in MySQL mithilfe von abgeleiteten Tabellen (ohne CTEs) geschrieben werden, die Verweise müssen jedoch wiederholt erfolgen.
Beispiel einer albernen Abfrage, die alle in den 50er Jahren und im Monat Juli geborenen Personen und die Anzahl aller im selben Jahr geborenen Personen anzeigt:
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 ;
In MySQL könnte es so geschrieben werden:
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 ;
Beachten Sie die Duplizierung des Codes für die abgeleitete Tabelle a
. Bei komplexeren Abfragen müsste Code mehrmals geschrieben werden.
Das wird funktionieren, aber es ist schade, dass die WITH-Klausel nicht den Vorteil bietet, dass dieselbe Abfrage nicht mehrmals ausgeführt werden muss (bei komplexen Abfragen kann dies sehr langsam und für die Datenbank-Engine sehr anstrengend sein; ich habe es gelitten). .
Ich würde vorschlagen, jedes in der ursprünglichen WITH-Klausel definierte SELECT in eine eigene temporäre Tabelle einzufügen und in der Abfrage zu verwenden . In MySQL wird die temporäre Tabelle automatisch gelöscht, sobald die Benutzersitzung endet.
BEARBEITEN:
Ich habe diese Antwort gerade in einem ähnlichen Thread gesehen, der die drei Problemumgehungen von MySQL deutlich macht :
/programming//a/1382618/2906290
und ein Beispiel für eine MySQL-Prozedur, die temporäre Tabellen erstellt und löscht, falls Sie Ihre Sitzung fortsetzen und diese Ressourcen freigeben möchten (ich würde es nur als Beispiel für die Syntax verwenden): /programming//a/ 5553145/2906290
quelle