Aggregati senza GROUP BY
Capire come un aggregato semplice riduce un'intera tabella a una sola riga
Aggregati senza GROUP BY è una lezione SQL Interview Prep gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento SQL Interview Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso SQL Interview Prep include 4 lezioni in totale.
Un aggregato, una riga
Con questa domanda gli intervistatori verificano un concetto fondamentale: «Cosa succede quando si usa una funzione di aggregazione senza GROUP BY?»
La risposta è: l'intera tabella si riduce a una sola riga. L'aggregato tratta tutte le righe che soddisfano i criteri come un unico grande gruppo implicito. Comprendere questo modello del «gruppo implicito» aiuta a spiegare molte regole successive, quindi lo analizziamo con attenzione.
Il gruppo implicito singolo
Quando si scrive un aggregato semplice senza GROUP BY, SQL si comporta come se esistesse un unico gruppo contenente ogni riga. Il risultato contiene sempre esattamente una riga, indipendentemente dal numero di righe della tabella — anche se la tabella è vuota.
Per esempio, SELECT COUNT(*) FROM employees restituisce una riga con un numero che riassume l'intera tabella.
SELECT COUNT(*) AS total_employees
FROM employees;
-- always returns exactly one rowPiù aggregati insieme
Si possono elencare più funzioni di aggregazione in un'unica SELECT. Tutte riassumono lo stesso gruppo implicito, quindi si ottiene comunque esattamente una riga con più colonne.
Questa è la query standard per ottenere le statistiche riepilogative. Tutti e quattro i numeri descrivono lo stesso insieme completo di righe.
SELECT
COUNT(*) AS num_rows,
SUM(salary) AS total_pay,
AVG(salary) AS avg_pay,
MAX(salary) AS top_pay
FROM employees;L'errore di combinazione
Ecco la regola più verificata. Non è possibile combinare un aggregato semplice con una colonna non aggregata nella stessa SELECT senza GROUP BY.
Perché? L'aggregato produce una riga, ma una colonna semplice ha molti valori — quale dovrebbe essere mostrato? La situazione è ambigua, quindi SQL standard genera un errore.
-- ERROR: name is not aggregated and there is no GROUP BY
SELECT name, MAX(salary)
FROM employees;Perché è ambiguo
Consideri la nostra tabella. MAX(salary) riduce tutte le righe a un unico valore. La colonna name, invece, ha un valore diverso in ogni riga. La singola riga di riepilogo non può contenere cinque nomi nella stessa cella.
Il database rifiuta di scegliere arbitrariamente. È lo stesso principio alla base della regola di GROUP BY: ogni colonna selezionata deve essere aggregata oppure far parte del gruppo. Senza GROUP BY, sono consentiti solo gli aggregati.
L'eccezione permissiva di MySQL
Vale la pena citare una particolarità di dialetto: le versioni meno recenti o non rigorose di MySQL consentivano la query con la combinazione e restituivano un nome arbitrario — non necessariamente quello della persona con lo stipendio più alto.
Le versioni moderne di MySQL con ONLY_FULL_GROUP_BY attivo, che oggi è l'impostazione predefinita, la rifiutano come gli altri DBMS. Menzionare questo aspetto dimostra consapevolezza delle differenze tra dialetti, ma bisogna sempre considerare errata la query con la combinazione.
Ottenere la riga associata al valore massimo
Come si ottiene quindi il nome del dipendente con lo stipendio più alto? Non combinando le colonne. Si usano ORDER BY + LIMIT, oppure una subquery che confronta il valore con l'aggregato.
La variante con ORDER BY/LIMIT è la più semplice. La variante con la subquery si generalizza bene e restituisce tutti i dipendenti a pari merito per il valore massimo.
-- Subquery: returns everyone earning the max
SELECT name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);Aggregati su una tabella vuota
Un caso limite che gli intervistatori inseriscono spesso è: «Cosa restituisce un aggregato semplice su una tabella vuota?»
COUNT(*)restituisce 0 (una riga con valore 0).SUM,AVG,MINeMAXrestituiscono NULL (una riga con valore NULL).
È importante notare che si ottiene comunque una riga, mai zero righe. Questa garanzia di una singola riga è proprio il punto di un aggregato senza GROUP BY.
SELECT COUNT(*) AS c, SUM(salary) AS s, MAX(salary) AS m
FROM employees
WHERE 1 = 0;
-- one row: c=0, s=NULL, m=NULLNiente aggregati in WHERE
Un'altra regola che deriva da questo modello è che non si può inserire un aggregato in una clausola WHERE, perché WHERE filtra le singole righe prima che avvenga l'aggregazione.
Per filtrare in base al risultato di un aggregato si usa HAVING (con il raggruppamento) oppure si racchiude l'aggregato in una subquery. WHERE viene semplicemente eseguito troppo presto nell'ordine di esecuzione per poter vedere l'aggregato.
-- ERROR: aggregate not allowed in WHERE
-- SELECT * FROM employees WHERE salary > AVG(salary);
-- Correct: compare to the aggregate via subquery
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);Aggregato senza GROUP BY vs GROUP BY
Metta a confronto i due casi:
- Senza GROUP BY: un gruppo implicito = l'intera tabella = esattamente una riga nel risultato.
- Con GROUP BY col: un gruppo per ogni valore distinto di col = una riga per gruppo.
Un aggregato semplice equivale a un GROUP BY con zero colonne di raggruppamento. Il meccanismo è lo stesso, ma tutto finisce in un unico grande contenitore.
-- Whole table: one row
SELECT AVG(salary) FROM employees;
-- Per department: one row each
SELECT department, AVG(salary)
FROM employees
GROUP BY department;Come spiegarlo
Una risposta chiara è: «Un aggregato senza GROUP BY tratta l'intero set di risultati come un unico gruppo implicito e restituisce esattamente una riga di riepilogo, anche su una tabella vuota. Non si può selezionare insieme una colonna non aggregata perché il suo valore sarebbe ambiguo. Per ottenere la riga associata a MAX o MIN, userei ORDER BY con LIMIT oppure una subquery che confronta il valore con l'aggregato.»
Verifica rapida
Preveda la forma del risultato.
Riepilogo
Gli aggregati senza GROUP BY in sintesi:
- L'intera tabella diventa un unico gruppo implicito → esattamente una riga nel risultato.
- Non si può combinare un aggregato semplice con una colonna non aggregata.
- Tabella vuota:
COUNT(*)= 0, gli altri restituiscono NULL, sempre in una sola riga. - Gli aggregati non possono comparire in
WHERE; si usa una subquery oppureHAVING. - Per ottenere la riga associata a MIN/MAX, si usano ORDER BY + LIMIT oppure una subquery.
Con questo si completano gli esercizi da colloquio sulle funzioni di aggregazione.
Domande Frequenti
La lezione «Aggregati senza GROUP BY» è gratuita?
Sì — il testo completo di «Aggregati senza GROUP BY» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso SQL Interview Prep, passa a CoddyKit PRO. Il corso SQL Interview Prep include 4 lezioni in totale.
Cosa imparerò in «Aggregati senza GROUP BY»?
Capire come un aggregato semplice riduce un'intera tabella a una sola riga Eserciti SQL Interview Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare SQL Interview Prep?
Non è richiesta alcuna esperienza precedente. SQL Interview Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Aggregati senza GROUP BY»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione SQL Interview Prep?
Sì. Ogni lezione SQL Interview Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- COUNT(*) contro COUNT(column) e COUNT(DISTINCT)
- SUM e AVG con i NULL
- MIN, MAX e aggregazione non numerica
- Aggregati senza GROUP BY