Vai al contenuto
eLearner.app
Modulo 4 · Lezione 4 di 416/57 nel corso~12 min
Lezioni del modulo (4/4)

Una query dentro un’altra: sottoquery

Hai imparato a estrarre, filtrare, raggruppare, unire e trasformare. C'è un'ultima idea fondamentale: mettere una query dentro un'altra. Si chiamano sottoquery (in inglese subqueries) e sono il passo che ti permette di rispondere a domande del tipo "chi guadagna sopra la media?" o "quali dipartimenti hanno qualcuno assegnato a un progetto?".

La sintassi base

Una sottoquery è una SELECT racchiusa fra parentesi tonde, usata al posto di un valore singolo o di una lista di valori in un'altra query:

SQL
-- Trova chi guadagna PIÙ DELLA MEDIA aziendale:
SELECT first_name, last_name, salary
FROM   employees
WHERE  salary > (SELECT AVG(salary) FROM employees);

Il motore esegue prima la sottoquery — SELECT AVG(salary) FROM employees restituisce un singolo numero — e poi usa quel numero nel WHERE esterno come se l'avessi scritto a mano. È esattamente questo il vantaggio: non devi sapere in anticipo quanto vale la media, è SQL a calcolarla per te.

I tre "tipi" più comuni

1. Sottoquery che restituisce un singolo valore

L'esempio sopra: la sottoquery produce una riga, una colonna (chiamata scalare). La usi con =, >, < ecc.

SQL
-- Dipendente con lo stipendio più alto:
SELECT first_name, last_name
FROM   employees
WHERE  salary = (SELECT MAX(salary) FROM employees);

2. Sottoquery che restituisce una lista

La sottoquery produce una colonna, molte righe. La usi con IN (...):

SQL
-- Dipartimenti che hanno almeno un dipendente:
SELECT name
FROM   departments
WHERE  id IN (SELECT DISTINCT department_id
              FROM employees
              WHERE department_id IS NOT NULL);

3. Sottoquery come "tabella" (FROM)

Una sottoquery può anche prendere il posto di una tabella nel FROM. È utile per pre-calcolare aggregati e poi filtrarli o unirli:

SQL
-- Dipartimenti con stipendio medio sopra i 40000:
SELECT d.name, medie.stipendio_medio
FROM   departments AS d
JOIN  (SELECT department_id, AVG(salary) AS stipendio_medio
       FROM employees
       GROUP BY department_id) AS medie
   ON d.id = medie.department_id
WHERE  medie.stipendio_medio > 40000;

Sottoquery o JOIN? Quando usare cosa

Spesso lo stesso risultato si può ottenere con un JOIN o con una sottoquery. Regola pratica:

  • Per filtrare righe di una tabella in base a una proprietà di un'altra ("dipendenti i cui dipartimenti sono…"), IN (subquery) è molto leggibile.
  • Per combinare colonne da più tabelle nel risultato, JOIN.
  • Per calcolare un aggregato e usarlo come soglia ("sopra la media"), la sottoquery scalare è la scelta naturale.

In pratica vedrai entrambi: il motore SQL spesso li ottimizza in modo identico. Scegli la forma che si legge meglio.

Prova tu

Esercizio#sql.m4.l4.e1
Tentativi: 0Caricamento…

Trova nome (first_name), cognome (last_name) e stipendio (salary) dei dipendenti che guadagnano STRETTAMENTE più della media aziendale. Tre colonne.

Caricamento editor…
Mostra suggerimento

Sostituisci ? con la sottoquery SELECT AVG(salary) FROM employees — restituisce un singolo numero da usare come soglia.

Soluzione disponibile dopo 3 tentativi

Esercizio di ripasso

Esercizio#sql.m4.l4.e2
Tentativi: 0Caricamento…

Elenca il nome (departments.name) dei dipartimenti che hanno almeno un dipendente con stipendio strettamente superiore a 50000. Usa una sottoquery con IN. Ordina alfabeticamente.

Caricamento editor…
Mostra suggerimento

La sottoquery interna restituisce gli id dei dipartimenti che hanno dipendenti con stipendio > 50000. Poi WHERE id IN (...) sull'esterna.

Soluzione disponibile dopo 3 tentativi