innestate e correlate
In alcuni casi (ma non in tutti) una subquery può essere trasformata in un join
equivalente, e viceversa
Le subquery sono dette anche query interne o istruzioni SELECT interne. L'istruzione
che include una subquery è detta anche query esterna o istruzione SELECT esterna
Le query interne possono a loro volta contenere altre query interne
Sono consentiti fino a 32 livelli di nidificazione
Una subquery può essere specificata in qualsiasi posizione in cui sia consentito
inserire un'espressione, a condizione che venga restituito un solo valore
ESEMPI
Le subquery sono query che compaiono all’interno di un'istruzione SELECT, INSERT,
UPDATE o DELETE o all’interno di un'altra query.
select E.*, (select Cnome from C where C.cc=E.cc)
from E
where E.voto>=28
UPDATE S
SET Acorso=3
WHERE SNome IN (Select D.Cnome
FROM D
WHERE D.CD like 'M%')
insert into D
select S.Matr, S.Snome, S.citta
from S
where S.ACorso=2
ESEMPI
Le subquery sono query che compaiono all’interno di un'istruzione SELECT,
INSERT, UPDATE o DELETE o all’interno di un'altra query.
Select S.Snome
From S
where S.Matr IN (select Matr
from E
where E.voto=30 or E.voto=33)
Subquery annidate
Le subquery annidate (o innestate, o nidificate)
◦ consistono di una query (“esterna”) con una clausola WHERE che
include condizioni dipendenti da risultati prodotti da altre query
(“interne”)
◦ le condizioni in cui compaiono le query interne sono tipicamente
quelle di confronto con insiemi di valori
“<> ALL” equivalente a “NOT IN”;
“IN” equivalente a “= ANY”
Subquery scalari annidate
Le subquery SCALARI annidate
NOTE:
◦ Non basarsi solo sulla rappresentazione grafica fornita da SQL server
◦ Partire dalle tabelle in cui non sono definiti dei legami di foreign key
(tabelle che possono essere riferite da altre tabelle), poi continuare con le
tabelle dipendenti.
Secondo passo - Cerchiamo le fotografie (idfotografia) che hanno ricevuto tale valutazione
Select idfotografia
from Valutazione
where voto= ( <valutazione_maggiore> )
Select idfotografia
from Valutazione
where voto >= ALL (select voto
from Valutazione)
15
Modifica esempio
QUERY: Elencare dati dei fotografi le cui fotografie hanno ricevuto la
valutazione più alta
Select F.*
from (Fotografo F join Fotografia FA on
(F.idfotografo=FA.idfotografo))
join Valutazione V on (V.idfotografia=FA.idfotografia)
where voto= (select MAX(voto)
from Valutazione)
Soluzione Alternativa
QUERY: Elencare dati dei fotografi le cui fotografie hanno ricevuto la valutazione più alta
Select *
from Fotografo
where idfotografo IN (select idfotografo
from Fotografia
where idfotografia IN (select idfotografia
from Valutazione
where voto= (select MAX(voto)
from Valutazione) ) )
Osservazioni
La SELECT innestata può essere ovunque; altro esempio –
selezionare idfotografia e voto medio di tutte le fotografie valutate
Select idfotografia, votomediototale =( select AVG(voto)
from Valutazione)
from Valutazione
Se la subquery viene introdotta da un operatore di confronto (=, < >, >, > =, <,
! >, ! <, or < =), allora deve riportare sempre un unico valore
WHERE idfotografo IN
(Select idfotografo
from Fotografo
WHERE nazionalita<>'italiano'
)
22
Alcuni esempi - Subquery come
operando scalare
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.
Select idfotografia
from Valutazione
where voto= (select MAX(voto)
from Valutazione)
Alcuni esempi - Subquery 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
"seleziona da t1 i valori di s1 che sono
WHERE s1 > ANY (SELECT s1 FROM t2); maggiori di almeno 1 dei valori di s1 su
t2".
Esempio: selezionare le foto che hanno almeno una valutazione uguale ad una
valutazione assegnata alla foto idfotografia=1
Select idfotografia
from Valutazione
where voto IN (select voto
from Valutazione where idfotografia=1)
Select idfotografia
from Valutazione
where voto <> ALL (select voto
from Valutazione where idfotografia=1)
Le query annidate formulate con NOT IN, ALL, NOT EXISTS (con subquery
correlata) non possono essere trasformate in query semplici con join
Esempio
Selezionare le foto che sono state valutate in uno dei concorsi in
cui è stata valutata la foto idfotografia=1
Select idfotografia
from Valutazione
where idconcorso IN (select idconcorso
from Valutazione where idfotografia=1)
è uguale a
Select V1.idfotografia
from Valutazione V1, Valutazione V2
where V1.idconcorso=V2.idconcorso
and V2.idfotografia=1
Subquery correlate
Le subquery CORRELATE sono subquery in cui il valore della SELECT interna è legato a
valori 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: in alcuni casi una subquery correlata è trasformabile in un join.
Esempio -Subquery correlate
Le subquery CORRELATE sono subquery in cui il valore della SELECT interna è
legato a valori della SELECT esterna
Con il group by