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:
-- 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.
-- 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 (...):
-- 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:
-- 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
Trova nome (first_name), cognome (last_name) e stipendio (salary) dei dipendenti che guadagnano STRETTAMENTE più della media aziendale. Tre colonne.
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
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.
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