Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 22 di 58
  • livello intermedio
Indice lezioni

Le subquery in MySQL

Una panoramica che mostra come creare ed eseguire query annidate, sfruttando il supporto di MySQL alle cosiddette subquery.
Una panoramica che mostra come creare ed eseguire query annidate, sfruttando il supporto di MySQL alle cosiddette subquery.
Link copiato negli appunti

All'epoca della loro introduzione con la versione 4.1 di MySQL, le subquery
sono state accolte dagli sviluppatori come una delle innovazioni più attese. A lungo infatti è stato sottolineato come la mancanza
di alcune funzionalità penalizzasse notevolmente MySQL nel confronto con
altri RDBMS, e l'assenza delle subquery era sicuramente fra quelle che
più si notavano.

Una subquery non è altro che una SELECT all'interno di un'altra
istruzione. Le subquery possono essere nidificate anche a profondità
notevoli.

Abbiamo già visto che ogni SELECT restituisce logicamente una tabella
formata da righe e colonne. Nel caso delle subquery è necessario fare una
distinzione: esse infatti possono restituire un valore singolo
(scalare)
, una singola riga, una
singola colonna, oppure una normale tabella. Le diverse
tipologie di subquery possono trovare posto in diversi punti
dell'istruzione.

MySQL subquery: come operano

Il caso più semplice di subquery è quella che restituisce un singolo
valore. La si può usare in qualsiasi punto sia possibile utilizzare un
valore di colonna. L'uso più frequente lo troviamo come operatore di
confronto:

SELECT colonna1 FROM t1
WHERE colonna1 = (SELECT MAX(colonna2) FROM t2);

Questa query estrae i valori di colonna1 nella tabella t1 che sono uguali
al valore massimo di colonna2 nella tabella t2.

Subquery MySQL che restituiscono colonne

Quando una subquery restituisce una colonna, può essere usata per fare
confronti attraverso gli operatori ANY,
SOME, IN e ALL:

SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);

La prima query significa "seleziona da t1 i valori di s1 che sono
maggiori di almeno 1 dei valori di s1 su t2". La seconda
invece seleziona i valori di s1 che sono uguali ad almeno
1
dei valori di s1 su t2. "IN" è sinonimo di "= ANY". "SOME" è
invece equivalente in tutto e per tutto ad "ANY".

SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);

Il significato qui è "seleziona da t1 i valori di s1 che sono maggiori di
tutti i valori di s1 su t2".
La clausola "NOT IN" equivale a "<> ALL".

Subquery MySQL che restituiscono righe

Quando una subquery restituisce una singola riga, può essere usata per
fare confronti attraverso i costruttori di righe:

SELECT colonna1,colonna2 FROM t1
WHERE (colonna1,colonna2) IN
(SELECT colonna1,colonna2 FROM t2);

Questa query estrae le righe di t1 in cui i valori di colonna1 e colonna2
sono ripetuti in una riga di t2. L'espressione "(colonna1,colonna2)" è,
appunto, un costruttore di riga, che poteva essere espresso anche come
"ROW(colonna1,colonna2)".

MySQL: Subquery correlate

Le subquery correlate sono quelle che contengono un riferimento ad una
tabella che fa parte della query esterna:

SELECT * FROM t1 WHERE colonna1 = ANY
(SELECT colonna1 FROM t2 WHERE t2.colonna2 =
t1.colonna2);

In questa subquery, la clausola WHERE contiene un riferimento alla
tabella t1, che tuttavia non è nominata nella clausola FROM della
subquery stessa: la troviamo infatti nella FROM della query esterna.

Query di questo tipo richiedono che la subquery venga rieseguita ad ogni
riga estratta dalla query esterna, e di conseguenza non sono molto
performanti. Meglio quindi evitarle quando possibile: spesso
infatti una subquery correlata è trasformabile in una join.

Le subquery correlate vengono usate a volte con le clausole
EXISTS e NOT EXISTS; la clausola EXISTS
è vera quando la subquery restituisce almeno una riga, mentre è falsa nel
caso opposto. Ovviamente NOT EXISTS funziona al contrario.

Un esempio:

SELECT DISTINCT tipoNegozio FROM negozi
WHERE EXISTS (SELECT * FROM negozi_citta
WHERE negozi_citta.tipoNegozio = negozi.tipoNegozio);

Ipotizzando che la tabella negozi_citta contenga i tipi di negozio
presenti nelle varie città, questa query estrae i tipi di negozio che
sono presenti in almeno una città.

Subquery nella FROM

E' possibile utilizzare una subquery anche nella clausola FROM, con
questa sintassi:

SELECT ... FROM (subquery) [AS] nome ...

Notate che è obbligatorio assegnare un nome alla subquery, per poterla
referenziare nelle altre parti della query. Ad esempio:

SELECT sq.*, t2.c1
FROM (SELECT c1, c2, c3 FROM t1 WHERE c1 > 5) AS sq
LEFT JOIN t2 ON sq.c1 = t2.c1;

In questo caso l'output della subquery viene chiamato "sq" ed il
riferimento è usato sia nella SELECT sia nella condizione di join.

Ti consigliamo anche