Equivalente MySQL di WITH in oracle


Risposte:


16

Non c'è. A meno che (fino a quando) non lo si sviluppa (MySQL è open-source, chiunque può contribuire).

La WITHparola 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 FROMclausola 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.


Per evitare la ripetizione (duplicazione del codice), non sarebbe meglio usare variabili e tabelle temporanee?
Pacerier,

Non mi preoccuperei della duplicazione del codice, ma certamente prenderei in considerazione e proverei una versione con tabelle temporanee, per motivi di prestazioni.
ypercubeᵀᴹ

1
Perché dici che non dovresti preoccuparti della duplicazione del codice? Questo è decisamente disordinato e non  ASCIUTTO .
Pacerier,

1
@Pacerier DRY non è sempre rilevante con il codice DB.
JNK,

1
@Pacerier Non sarei sorpreso se non lo fosse. I motori DB devono fare ipotesi ponderate su ciò che funzionerà meglio garantendo comunque di restituire risultati corretti. Le tabelle temporanee in generale vanno bene, ma DRY porta a prestazioni terribili nei DB sotto altri aspetti, come le funzioni definite dall'utente.
JNK,

2

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 :

  • Tabelle temporanee
  • Tavole DERIVATE
  • viste incorporate (effettivamente ciò che rappresenta la clausola WITH - sono intercambiabili)

/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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.