Una subquery è una query annidata dentro un'altra query — utilizzata in WHERE, FROM, SELECT, o con EXISTS. Ti permette di utilizzare il risultato di una query all'interno di un'altra, abilitando filtraggi e computazioni complesse.
Una subquery è una query annidata dentro un'altra query — utilizzata in WHERE, FROM, SELECT, o con EXISTS. Ti permette di utilizzare il risultato di una query all'interno di un'altra, abilitando filtraggi e computazioni complesse.
-- find users who have placed an order (their id is in the orders table)
SELECT name FROM users
WHERE id IN (SELECT user_id FROM orders); -- the subquery returns a list of user_ids
-- find products more expensive than the average
SELECT name, price FROM products
WHERE price > (SELECT AVG(price) FROM products); -- subquery returns a single value
Una subquery in WHERE fornisce valori su cui filtrare — una lista (con IN) o un singolo valore (con operatori di confronto).
-- for each user, find those with above-average orders FOR THEIR COUNTRY
SELECT name FROM users u
WHERE order_count > (
SELECT AVG(order_count) FROM users
WHERE country = u.country -- references the OUTER query's row (correlated)
);
Una subquery correlata referenzia la query esterna — viene eseguita una volta per ogni riga esterna (potenzialmente più lenta). Una subquery non correlata viene eseguita una sola volta.
-- users who have at least one order (often more efficient than IN)
SELECT name FROM users u
WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.user_id = u.id -- just checks existence
);
EXISTS verifica se una subquery restituisce almeno una riga — spesso più efficiente di IN per i controlli di esistenza (può fermarsi alla prima corrispondenza).
-- use a subquery result as a table
SELECT country, avg_age FROM (
SELECT country, AVG(age) AS avg_age FROM users GROUP BY country
) AS country_stats
WHERE avg_age > 30;
Many subqueries can be rewritten as JOINs (often more efficient/readable).
WHERE id IN (SELECT ...) → can often be a JOIN
Use subqueries for clarity in filtering/aggregation; JOINs for combining data.
CTEs (WITH) are often a cleaner alternative to complex nested subqueries.
Le subquery sono una tecnica SQL importante per query complesse — utilizzare il risultato di una query all'interno di un'altra abilita filtraggi e computazioni che le query semplici non riescono ad esprimere, quindi comprenderle è prezioso per scrivere query realistiche.
Conoscere le forme — subquery in WHERE (filtraggio tramite una lista con IN o un singolo valore con confronti), subquery correlate (referenziando la query esterna, eseguite per riga), EXISTS (controlli di esistenza efficienti), e subquery in FROM (derived table) — copre i pattern comuni per esprimere logica complessa.
Comprendere la distinzione tra subquery correlate e non correlate è importante per le prestazioni (le subquery correlate vengono eseguite una volta per ogni riga esterna e possono essere lente).
Equalmente prezioso è conoscere la relazione con JOIN e CTE: molte subquery possono essere riscritte come JOIN (spesso più efficienti e leggibili) o CTE (più pulite per casi complessi), quindi comprendere quando utilizzare ognuna — subquery per chiarezza di filtraggio/aggregazione, JOIN per combinare dati — è un'abilità pratica.
Poiché le query realistiche spesso richiedono annidamento (filtraggio in base a risultati aggregati, controlli di esistenza, confronto con valori calcolati), e poiché comprendere le subquery, le loro caratteristiche di prestazione (specialmente quelle correlate), e la loro relazione con JOIN/CTE è importante per scrivere query complesse efficaci ed efficienti, padroneggiare le subquery è una conoscenza preziosa e frequentemente applicata per SQL oltre le query di base e un argomento comune nei colloqui che dimostra la capacità di esprimere requisiti di dati complessi.