La regola di GROUP BY per le colonne SELECT
Capire perché ogni colonna non aggregata deve comparire in GROUP BY e conoscere la modalità only-full-group-by
La regola di GROUP BY per le colonne SELECT è una lezione SQL Interview Prep gratuita su CoddyKit. Questa è la lezione 1 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.
Perché nei colloqui si parte da GROUP BY
GROUP BY è il punto in cui i colloqui distinguono i profili junior da quelli di livello intermedio. La regola che viene verificata più spesso è una sola: ogni colonna nell'elenco SELECT deve trovarsi all'interno di una funzione aggregata oppure essere elencata in GROUP BY.
Se infrange questa regola, il motore non può decidere quale valore mostrare per un gruppo composto da molte righe. Chi conduce il colloquio inserisce proprio questo errore per verificare se Lei comprende che cosa sia davvero un gruppo.
Che cos'è davvero un gruppo
GROUP BY riduce molte righe a una riga per ogni chiave distinta. Dopo il raggruppamento, il motore non dispone più delle singole righe. Ha soltanto una riga riepilogativa per ogni gruppo.
- Le colonne usate per il raggruppamento hanno un unico valore definito per ogni gruppo.
- Gli aggregati come
COUNT,SUMeAVGriducono i molti valori a uno solo. - Qualsiasi altra colonna non aggregata è ambigua: quale dei molti valori dovrebbe essere mostrato?
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department;L'errore classico
Ecco l'errore che chi conduce i colloqui ama incontrare. Si raggruppa per department, ma si seleziona anche name, una colonna non aggregata che non è presente in GROUP BY.
Ogni reparto ha molti dipendenti, quindi per ogni gruppo ci sono molti nomi. Il motore non può sceglierne uno, perciò lo standard SQL rifiuta la query.
-- ERROR: name is not in GROUP BY and not aggregated
SELECT department, name, COUNT(*)
FROM employees
GROUP BY department;Due modi per correggerlo
Esistono due correzioni valide, e chi conduce il colloquio vuole sapere che è consapevole del fatto che producono risultati diversi:
- Aggiungere la colonna a GROUP BY se desidera davvero un raggruppamento più dettagliato (una riga per reparto e nome).
- Racchiuderla in un aggregato come
MAX(name)oCOUNT(name)se desidera un unico valore per ogni gruppo esistente.
-- Finer grouping
SELECT department, name, COUNT(*) AS rows_for_person
FROM employees
GROUP BY department, name;ONLY_FULL_GROUP_BY in MySQL
Un errore ricorrente: le versioni precedenti di MySQL consentivano di selezionare colonne non incluse nel raggruppamento e restituivano silenziosamente un valore arbitrario del gruppo. Questo produceva report errati, ma dall'aspetto corretto.
Le versioni moderne di MySQL abilitano per impostazione predefinita ONLY_FULL_GROUP_BY, che impone la regola standard. Postgres, SQL Server e Oracle l'hanno sempre imposta. Se Le chiedono perché una query «funzionava sul vecchio server ma ora si interrompe», questa è la risposta.
-- Legal under ONLY_FULL_GROUP_BY because every
-- selected column is grouped or aggregated
SELECT department, MAX(hire_date) AS latest_hire
FROM employees
GROUP BY department;Eccezione della dipendenza funzionale
C'è una sottigliezza con cui chi conduce i colloqui verifica il livello di approfondimento. Se raggruppa per la chiave primaria di una tabella, ogni altra colonna della tabella è funzionalmente dipendente dalla chiave, quindi ha esattamente un valore per ogni gruppo.
Postgres e le versioni moderne di MySQL consentono di selezionare queste colonne dipendenti senza elencarle. La chiave raggruppata le determina in modo univoco, quindi non c'è ambiguità.
-- Legal: id is the PK, so name is determined by it
SELECT e.id, e.name, COUNT(o.id) AS orders
FROM employees e
LEFT JOIN orders o ON o.employee_id = e.id
GROUP BY e.id;Esempio svolto: vendite per area geografica
Supponga di dover elaborare un report sulle vendite totali per area geografica. La chiave di raggruppamento è region; la misura è SUM(amount). Tutto il resto deve essere aggregato o escluso.
Noti quanto sia ordinato il risultato: una riga per area geografica, ciascuna con un unico valore ottenuto dalla somma. Questa è la struttura di ogni report aggregato.
SELECT region,
SUM(amount) AS total_sales,
COUNT(*) AS num_orders,
AVG(amount) AS avg_order
FROM sales
GROUP BY region;Mescolare dettaglio e riepilogo
Una richiesta insidiosa: «Mostrare l'importo di ogni ordine insieme al totale della sua area geografica». Non è possibile farlo con un semplice GROUP BY, perché il raggruppamento elimina le singole righe.
La risposta corretta è una funzione finestra (SUM(amount) OVER (PARTITION BY region)) oppure un join alla sottoquery raggruppata. Il punto della domanda è riconoscere che GROUP BY è lo strumento sbagliato in questo caso.
-- Detail rows kept, region total added per row
SELECT order_id, region, amount,
SUM(amount) OVER (PARTITION BY region) AS region_total
FROM sales;GROUP BY e gli alias di SELECT
È possibile usare in GROUP BY un alias definito in SELECT? Dipende dal dialetto SQL, e proprio questa incoerenza è ciò che spesso viene verificato nei colloqui.
- MySQL e Postgres: consentono di raggruppare usando un alias di SELECT.
- SQL Server e Oracle: non lo consentono; è necessario ripetere l'espressione completa.
La risposta compatibile con tutti i dialetti consiste nel ripetere l'espressione in GROUP BY, una soluzione che funziona ovunque.
-- Portable: repeat the expression rather than the alias
SELECT EXTRACT(YEAR FROM order_date) AS yr, COUNT(*)
FROM sales
GROUP BY EXTRACT(YEAR FROM order_date);DISTINCT o GROUP BY per ottenere l'unicità
Se desidera solo combinazioni distinte e non deve calcolare aggregati, GROUP BY senza aggregati si comporta come DISTINCT. Durante un colloquio potrebbe esserLe chiesto quale delle due esprima meglio l'intento.
Usi DISTINCT per esprimere l'intento («voglio righe univoche»). Riservi GROUP BY ai casi in cui calcola anche degli aggregati. Il risultato è lo stesso, ma il segnale per chi legge è diverso.
-- These return the same rows
SELECT DISTINCT department, role FROM employees;
SELECT department, role FROM employees GROUP BY department, role;Come esprimerlo durante il colloquio
Quando affronta una domanda su GROUP BY, esponga a voce la regola: «Ogni colonna selezionata è una chiave di raggruppamento oppure è racchiusa in un aggregato, perché il raggruppamento lascia una riga per ogni chiave.»
Indichi poi la chiave di raggruppamento e le misure, verificando che nessun elemento rimanga fuori dal raggruppamento. Una risposta strutturata di questo tipo dimostra una competenza di livello intermedio ancora prima di scrivere la query.
Verifica rapida
Verifichi la Sua comprensione della regola fondamentale di GROUP BY.
Riepilogo
La regola: ogni colonna di SELECT è una chiave di raggruppamento oppure un aggregato. Il motivo: GROUP BY lascia una riga per ogni chiave, quindi le colonne originali non raggruppate risultano ambigue.
- Corregga le violazioni raggruppando la colonna o applicandole un aggregato.
- Il vecchio comportamento di MySQL restituiva valori arbitrari;
ONLY_FULL_GROUP_BYapplica lo standard. - La dipendenza funzionale dalla chiave primaria è l'unica eccezione consentita.
- Per mantenere le righe di dettaglio accanto ai totali dei gruppi, utilizzi le funzioni finestra, non GROUP BY.
Domande Frequenti
La lezione «La regola di GROUP BY per le colonne SELECT» è gratuita?
Sì — il testo completo di «La regola di GROUP BY per le colonne SELECT» è 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 «La regola di GROUP BY per le colonne SELECT»?
Capire perché ogni colonna non aggregata deve comparire in GROUP BY e conoscere la modalità only-full-group-by 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 1 di 4.
Quanto tempo richiede la lezione «La regola di GROUP BY per le colonne SELECT»?
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
- La regola di GROUP BY per le colonne SELECT
- HAVING e WHERE
- Raggruppare per più colonne ed espressioni
- Contare e filtrare i gruppi