Torna all'elenco degli articoli Articoli
Tempo di lettura: 7 minuti

Quali sono i diversi tipi di subquery SQL?

Le subquery possono essere utilizzate in molti casi aziendali. Quali tipi di subquery offre SQL? E come si possono utilizzare in modo efficiente? In questo articolo vi guiderò attraverso i diversi tipi di subquery e le situazioni tipiche in cui sono utili.

Che cos'è una subquery in SQL?

Una subquery, o query annidata, è una query inserita all'interno di un'altra query SQL. Ci sono molti scenari diversi in cui è possibile includere una query nelle clausole WHERE, FROM o SELECT della query principale.

È sempre più facile afferrare nuovi concetti quando vengono presentati con degli esempi. Quindi, cominciamo! Immaginiamo di gestire diverse gallerie d'arte e di avere le seguenti tabelle nel nostro database:

galleries

idcity
1London
2New York
3Munich

paintings

idnamegallery_idprice
1Patterns35000
2Ringer14500
3Gift13200
4Violin Lessons26700
5Curiosity29800

sales_agents

idlast_namefirst_namegallery_idagency_fee
1BrownDenis22250
2WhiteKate33120
3BlackSarah21640
4SmithHelen14500
5StewartTom32130

managers

idgallery_id
12
23
41

Uno dei casi più semplici di utilizzo delle sottoquery è quello di includerle nella clausola WHERE per filtrare i risultati. Ad esempio, se si desidera visualizzare le informazioni relative ai soli agenti di vendita che il mese scorso hanno ricevuto una commissione di agenzia superiore alla media, è possibile utilizzare la seguente query SQL:

SELECT *
FROM sales_agents
WHERE agency_fee > 
(SELECT AVG(agency_fee)
 FROM sales_agents);

In questo caso, la sottoquery calcola il compenso medio ricevuto dal team di vendita il mese scorso e restituisce un singolo valore (2728 dollari). Quindi si utilizza questo valore per filtrare i risultati della query principale e restituire le informazioni solo per gli agenti di vendita il cui compenso di agenzia è stato superiore alla media:

idlast_namefirst_namegallery_idagency_fee
2WhiteKate33120
4SmithHelen14500

Le subquery SQL possono restituire singoli valori o intere tabelle. Possono esserci subquery annidate o correlate. Ognuno di questi tipi di subquery è adatto a determinati casi d'uso. Se desiderate informazioni più dettagliate, leggete la nostra guida per principianti alle subquery SQL. In questo articolo, fornirò esempi di diversi tipi di subquery in SQL e vi guiderò attraverso gli scenari tipici in cui questo tipo di subquery è particolarmente utile.

Subquery scalari

Quando una subquery restituisce un singolo valore, o esattamente una riga e una colonna, la chiamiamo subquery scalare. Questo tipo di subquery viene spesso utilizzato nella clausola WHERE per filtrare i risultati della query principale. La subquery dell'esempio precedente è una subquery scalare, in quanto restituisce un singolo valore (cioè la tariffa media dell'agenzia).

Le sottoquery scalari possono essere utilizzate anche nell'istruzione SELECT della query principale. Ad esempio, supponiamo di voler vedere il prezzo medio di tutti i nostri quadri accanto al prezzo di ciascun quadro.

SELECT name AS painting,
	 price,
	 (SELECT AVG(price)
  FROM paintings) AS avg_price
FROM paintings;

La sottoquery restituisce un valore scalare (5840 dollari) che viene semplicemente aggiunto a ogni riga della tabella risultante:

paintingpriceavg_price
Patterns50005840
Ringer45005840
Gift32005840
Violin Lessons67005840
Curiosity98005840

Si noti che in questo esempio la sottoquery (detta anche query interna) è totalmente indipendente dalla query principale (detta anche query esterna): è possibile eseguire la query interna da sola e ottenere un risultato significativo.

Subquery a più righe

Se la subquery restituisce più di una riga, può essere definita una subquery a righe multiple. Questo tipo di subquery include (1) subquery che restituiscono una colonna con più righe (cioè un elenco di valori) e (2) subquery che restituiscono più colonne con più righe (cioè tabelle).

Le sottoquery che restituiscono una colonna e più righe sono spesso incluse nella clausola WHERE per filtrare i risultati della query principale. In questo caso, vengono solitamente utilizzate con operatori come IN, NOT IN, ANY, ALL, EXISTS o NOT EXISTS che consentono di confrontare un particolare valore con i valori dell'elenco restituito dalla subquery.

Volete saperne di più sulle subquery SQL con l'operatore IN? Guardate un episodio della nostra serie We Learn SQL su Youtube. Ricordatevi di iscrivervi al nostro canale.

Per esempio, supponiamo di voler calcolare la tariffa media di agenzia per gli agenti che non sono manager. Per rispondere a questa domanda si può utilizzare la seguente sottoquery:

SELECT AVG(agency_fee)
FROM sales_agents
WHERE id NOT IN (SELECT id
                 FROM managers);

La query interna restituirà un elenco di tutti gli ID dei manager. La query esterna filtra solo gli agenti di vendita che non sono nell'elenco dei manager e calcola la commissione media di agenzia pagata a questi agenti. La query restituisce un unico valore: la commissione media di agenzia pagata ai non manager (1885 dollari).

Consultate la nostra guida alle subquery SQL per altri esempi di subquery a più righe.

Subquery correlate

Esistono anche subquery SQL in cui la query interna si basa su informazioni ottenute dalla query esterna. Si tratta delle subquery correlate. A causa dell'interdipendenza tra la query principale e quella interna, questo tipo di subquery può essere più difficile da capire. Leggete questa guida per principianti per diventare più esperti con le subquery correlate in SQL.

Ancora una volta, passiamo direttamente agli esempi! Le subquery correlate sono comunemente utilizzate nelle istruzioni SELECT, WHERE e FROM.

Se vogliamo calcolare il numero di dipinti presenti in ciascuna delle nostre gallerie, possiamo utilizzare la seguente query. Si noti la sottoquery correlata nell'istruzione SELECT:

SELECT city, 
 (SELECT count(*)
  FROM paintings p
  WHERE g.id = p.gallery_id) total_paintings
FROM galleries g;

In questo caso, la sottoquery restituisce un valore scalare con il numero totale di dipinti nella galleria corrispondente. La query principale visualizza questa informazione insieme alla città in cui si trova la galleria d'arte.

citytotal_paintings
London2
New York2
Munich1

Si può anche notare che, a differenza degli esempi precedenti, qui la query interna dipende da quella esterna. Prendiamo l'ID della galleria dalla tabella galleries che si trova nella query esterna. In altre parole, non è possibile eseguire la query interna come una query indipendente: si otterrà un errore.

Si noti anche che, in questo caso, si potrebbe usare una JOIN invece di una subquery e ottenere lo stesso risultato:

SELECT g.city, count(p.name) AS total_paintings
FROM galleries g
JOIN paintings p
ON g.id = p.gallery_id
GROUP BY g.city;

Le JOIN di solito sono più veloci delle subquery. Tuttavia, se si ritiene che le subquery siano più intuitive per il proprio caso specifico, è bene utilizzarle. Per ulteriori informazioni sull'uso delle subquery rispetto alle JOIN, consultare la nostra guida completa.

Infine, le subquery correlate possono essere utilizzate anche nell'istruzione WHERE. Per esempio, supponiamo di voler ottenere informazioni sugli agenti di vendita il cui compenso di agenzia è uguale o superiore al compenso medio della loro galleria. Per ottenere il risultato desiderato, si può eseguire la seguente query:

SELECT last_name, 
       first_name, 
       agency_fee
FROM sales_agents sa1
WHERE sa1.agency_fee >= (SELECT avg(agency_fee)
                         FROM sales_agents sa2 
                         WHERE sa2.gallery_id = sa1.gallery_id);

La query interna, in questo caso, restituisce la tariffa media di agenzia per la galleria del rispettivo agente di vendita. La query esterna restituisce le informazioni relative ai soli agenti di vendita che soddisfano la condizione inclusa nell'istruzione WHERE (ossia una provvigione pari o superiore alla media della loro galleria).

last_namefirst_nameagency_fee
BrownDenis2250
WhiteKate3120
SmithHelen4500

Anche in questo esempio la sottoquery è una sottoquery correlata, in quanto non può essere eseguita indipendentemente dalla query esterna. Se volete saperne di più, date un'occhiata a questo tutorial facile da seguire sulla scrittura di subquery correlate.

Anche se i diversi tipi di subquery SQL coprono molte situazioni tipiche, in alcuni casi è possibile utilizzare le Espressioni di tabella comuni (CTE) invece delle subquery. Se siete interessati a saperne di più sulle CTE, consultate questo articolo che vi guiderà alla scoperta delle differenze tra subquery e CTE.

È ora di fare pratica con i diversi tipi di subquery SQL!

Avete imparato che in SQL esistono molti tipi di subquery. A seconda del compito da svolgere, è possibile applicare subquery scalari, a più righe o correlate per ottenere il risultato desiderato.

Abbiamo già visto diversi esempi di subquery e abbiamo scoperto dove è possibile utilizzarle. Tuttavia, per diventare un utente SQL davvero potente, è necessario fare più pratica con i diversi tipi di subquery. È il momento di fare esercizi interattivi!

Il nostro SQL Basics ha una sezione completa sulle subquery, dove spiegazioni dettagliate ed esempi sono abbinati a decine di esercizi. Dateci un'occhiata! Per fare ulteriore pratica, vi consiglio anche di completare la sezione "Subqueries" del corso SQL Practice Set.

Più pratica = query SQL più professionali! Buon apprendimento!