Esiste un equivalente MySQL della clausola WITH in Oracle?
Esiste un equivalente MySQL della clausola WITH in Oracle?
Risposte:
Non c'è. A meno che (fino a quando) non lo si sviluppa (MySQL è open-source, chiunque può contribuire).
La WITH
parola chiave ANSI / ISO SQL viene utilizzata per definire Common Table Expressions (CTE) e semplifica le query complesse con uno o più riferimenti nidificati. È disponibile in Oracle, Postgres, SQL-Server, DB2 ma non in MySQL.
La query finale può avere riferimenti (in genere nella FROM
clausola ma potrebbero trovarsi in qualsiasi altra parte) a una qualsiasi delle espressioni comuni della tabella, una o più volte. La query può essere scritta (senza CTE) in MySQL usando tabelle derivate ma i riferimenti devono essere fatti ripetutamente.
Esempio di una domanda stupida che mostra tutte le persone nate negli anni '50 e nel mese di luglio e il numero di tutte le persone nate nello stesso anno:
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, potrebbe essere scritto come:
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 ;
Notare la duplicazione del codice per la tabella derivata a
. Nelle query più complesse, il codice dovrebbe essere scritto più volte.
Funzionerà ma è un peccato che non fornisca il vantaggio di utilizzare la clausola WITH, ovvero di non eseguire più volte la stessa query (con query complesse potrebbe essere in realtà lente e molto impegnative per il motore di database; l'ho subito) .
Suggerirei di inserire ogni SELECT definito nella clausola WITH originale nella sua tabella temporanea e di usarli all'interno della query . In MySQL, la tabella temporanea verrà rilasciata automaticamente al termine della sessione dell'utente.
MODIFICARE:
Ho appena visto questa risposta in un thread simile che espone chiaramente le 3 soluzioni alternative con MySQL :
/programming//a/1382618/2906290
e un esempio della procedura MySQL che crea e elimina le tabelle temporanee nel caso in cui tu continui con la sessione e desideri liberare quelle risorse (lo userei solo come esempio della sintassi): /programming//a/ 5553145/2906290