Lezione 4: Subquery — Quando un Solo Query Non Basta!


Lesson 4

Lezione 4: Subquery — Quando un Solo Query Non Basta!

Bentornato, avventuriero dei dati! Se sei arrivato fin qui, probabilmente pensi: “Questa roba di SQL è un gioco da ragazzi.” Ma appena credi di essere il padrone del tuo regno di tabelle, PostgreSQL tira fuori l’asso nella manica: Subquery. E qui le cose iniziano a farsi interessanti. Pensa alle subquery come a missioni segrete — piccole query nascoste dentro quelle più grandi, che fanno il lavoro sporco dietro le quinte.

Che cos’è una Subquery?

Immagina di essere al ristorante. Hai appena ordinato una pizza (la query principale), ma poi sussurri al cameriere: “A proposito, aggiungi delle olive extra se sono disponibili.” Ecco la tua subquery! Una subquery è una query annidata all’interno di un’altra query, usata per raffinare o estendere il risultato della query principale.

Le subquery sono perfette per quei momenti in cui un’unica query non basta, ad esempio:

  • Trovare i cavalieri migliori (in base alle missioni completate).
  • Scoprire quali draghi hanno bruciato più di tre villaggi.
  • Identificare quali cavalieri hanno bisogno di… ehm, un po’ più di allenamento.

Tipi di Subquery

Le subquery vengono in vari gusti, a seconda di come e dove le utilizzi. Facciamo la conoscenza con i nostri principali protagonisti:

  1. Subquery a Singola Riga: Restituiscono una sola riga. Sono come dare una rapida sbirciata.
  2. Subquery a Più Righe: Restituiscono più righe. Perfette per confrontare elenchi!
  3. Subquery Scalari: Restituiscono un singolo valore. Ideali per confronti segreti.
  4. Subquery Correlate: Questi sono le spie — sanno cosa succede nella query principale e si adattano in tempo reale.

Ora vediamo queste subquery in azione!

Usare le Subquery con SELECT

Cominciamo con un esempio semplice. Supponiamo che tu abbia una tabella cavalieri e voglia sapere quale cavaliere ha completato più missioni:

SELECT nome
FROM cavalieri
WHERE missioni_completate = (SELECT MAX(missioni_completate) FROM cavalieri);

Questa piccola subquery (SELECT MAX(missioni_completate) FROM cavalieri) fa il suo dovere, calcola il numero massimo di missioni completate e torna con il risultato. A quel punto, la query principale dice: “Mostrami solo i cavalieri con questo numero di missioni.”

Subquery nel FROM

Ora, supponiamo di voler raggruppare i cavalieri per regno e vedere la media delle missioni completate. Una query normale potrebbe impantanarsi, ma una subquery nel FROM viene a salvarci:

SELECT regno, AVG(missioni_completate)
FROM (SELECT nome, regno, missioni_completate FROM cavalieri) AS sub_cavalieri
GROUP BY regno;

Qui, la nostra subquery funziona come una tabella temporanea, restringendo i dati prima che la query principale li elabori.

Subquery nella Clausola WHERE

Le subquery sono spesso usate nella clausola WHERE per definire condizioni. Immagina di voler trovare i cavalieri che hanno completato più missioni della media:

SELECT nome
FROM cavalieri
WHERE missioni_completate > (SELECT AVG(missioni_completate) FROM cavalieri);

La subquery calcola la media, e poi la query principale dice: “Mostrami solo i cavalieri sopra la media!” (Quelli che si sono dati più da fare, insomma.)

Subquery Correlate: Le Spie del SQL

Le subquery correlate sono le più astute di tutte. Si eseguono per ogni riga della query principale e possono fare riferimento a colonne della query principale stessa. Supponiamo di voler sapere quali cavalieri hanno completato più missioni della media del loro regno:

SELECT nome, regno
FROM cavalieri AS c1
WHERE missioni_completate > (SELECT AVG(missioni_completate) 
                            FROM cavalieri AS c2 
                            WHERE c2.regno = c1.regno);

Qui, la subquery calcola la media delle missioni per ogni regno dinamicamente. È come una spia nella query principale, che raccoglie informazioni e le trasmette.

Subquery nella Clausola SELECT

Infine, parliamo delle subquery nella clausola SELECT. Supponiamo che tu voglia un report che mostri il nome di ciascun cavaliere e come si confronta con la media totale delle missioni completate:

SELECT nome, 
       missioni_completate, 
       (SELECT AVG(missioni_completate) FROM cavalieri) AS media_generale
FROM cavalieri;

Ora hai un confronto chiaro, tutto grazie a quella subquery discreta e nascosta lì dentro.

Tiriamo le Somme: Un Grande Show delle Subquery!

Ecco un esempio che mette insieme tutto quello che abbiamo imparato:

Vuoi trovare i cavalieri che hanno completato più missioni della media generale, ma solo se appartengono a regni in cui la media delle missioni è maggiore di 3. Sembra complicato? Ecco la magia:

SELECT nome
FROM cavalieri
WHERE missioni_completate > (SELECT AVG(missioni_completate) 
                            FROM cavalieri) 
AND regno IN (SELECT regno 
                FROM cavalieri 
                GROUP BY regno 
                HAVING AVG(missioni_completate) > 3);

Questo mostro di query utilizza subquery sia nella clausola WHERE che nella condizione IN. È come comandare un intero esercito di piccole query!

Cosa Abbiamo Imparato Oggi?

Oggi abbiamo esplorato il mondo delle subquery:

  • Subquery a Singola Riga: Restituiscono una riga, usate per confronti precisi.
  • Subquery a Più Righe: Restituiscono più righe, perfette per elenchi.
  • Subquery Scalari: Restituiscono un singolo valore.
  • Subquery Correlate: Si adattano alla query principale dinamicamente.

E Adesso?

Nella prossima lezione esploreremo CTE e Funzioni Finestra. Preparati a portare le tue abilità SQL al livello successivo!


Benvenuto nel mondo delle subquery. Che le tue query annidate siano sempre precise e i tuoi risultati senza errori!