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

Raggruppare con GROUP BY

Nel Modulo 2 hai imparato che COUNT(*), AVG(...), SUM(...) riducono tutte le righe a una sola riga di risultato. Ma cosa succede se vuoi una media stipendio per ogni dipartimento, non per l'intera azienda? Vuoi una riga per ogni gruppo. È il lavoro di GROUP BY.

La sintassi

SQL
SELECT colonna_di_raggruppamento, FUNZIONE_AGGREGATA(...)
FROM   tabella
GROUP BY colonna_di_raggruppamento;

Letta in italiano: "dividi le righe in gruppi che hanno lo stesso valore di colonna_di_raggruppamento, e per ogni gruppo calcola l'aggregato".

SQL
-- Stipendio medio per dipartimento:
SELECT department_id, AVG(salary) AS average
FROM   employees
GROUP BY department_id;

Il risultato ha una riga per ogni department_id distinto trovato in employees. Otterrai 5 righe: una per ciascuno dei 4 dipartimenti (1, 2, 3, 4) più una per NULL (Andrea Costa).

Con JOIN per nomi leggibili

Spesso vuoi raggruppare per department_id ma mostrare il nome del dipartimento. Si combina GROUP BY con un JOIN:

SQL
SELECT d.name AS department,
       COUNT(*)    AS count,
       AVG(e.salary) AS average_salary
FROM   employees   AS e
JOIN   departments AS d ON e.department_id = d.id
GROUP BY d.name
ORDER BY count DESC;

Questa è una query di business intelligence in piena regola: in tre righe ti dice quanti dipendenti ha ogni dipartimento e quanto guadagnano in media, ordinati dal più grande al più piccolo.

La regola d'oro

Quando usi GROUP BY, ogni colonna nella SELECT deve essere:

  1. una delle colonne di raggruppamento (es. department_id, d.name), o
  2. dentro una funzione di aggregazione (es. AVG(salary), COUNT(*)).
SQL
-- ERRORE: first_name non è né nel GROUP BY né dentro un aggregato
SELECT department_id, first_name, AVG(salary)
FROM   employees
GROUP BY department_id;

PostgreSQL ti restituisce un errore esplicito ("column must appear in the GROUP BY clause or be used in an aggregate function"). È un errore comune delle prime settimane: se lo vedi, fermati e chiediti "qual è il valore di first_name per un gruppo di 3 persone?" — non c'è una risposta singola, ed è per questo che il motore si rifiuta.

Prova tu

Esercizio#sql.m3.l3.e1
Tentativi: 0Caricamento…

Per ogni dipartimento, calcola quanti dipendenti contiene. Restituisci due colonne: il nome del dipartimento (departments.name) e il conteggio dei dipendenti. Una riga per dipartimento.

Caricamento editor…
Mostra suggerimento

Aggrega con COUNT(*) e raggruppa per d.name. La SELECT deve contenere solo la colonna di raggruppamento e l'aggregato.

Soluzione disponibile dopo 3 tentativi

Esercizio di ripasso

Esercizio#sql.m3.l3.e2
Tentativi: 0Caricamento…

Per ogni dipartimento (departments.name), calcola lo stipendio medio (AVG(salary)) dei suoi dipendenti, ordinato dal più alto al più basso.

Caricamento editor…
Mostra suggerimento

AVG(e.salary) come aggregato, GROUP BY d.name, ORDER BY average DESC.

Soluzione disponibile dopo 3 tentativi