CodeGym /Corsi /SQL SELF /Filtraggio dei dati aggregati con HAVING

Filtraggio dei dati aggregati con HAVING

SQL SELF
Livello 8 , Lezione 1
Disponibile

Ecco una cosa di cui non abbiamo ancora parlato: come filtrare i gruppi dopo aver applicato le funzioni di aggregazione? A volte non ci servono tutte le facoltà — solo quelle dove ci sono più di cento studenti. Oppure ci interessa vedere solo i reparti dove lo stipendio medio supera i 50.000. Oggi vediamo come filtrare i dati aggregati usando HAVING.

Perché ci serve HAVING se abbiamo già WHERE? Non si può semplicemente mettere WHERE dopo GROUP BY? :)

Non è così semplice! Prima di tutto, l'ordine degli operatori in SQL è fisso e WHERE viene eseguito prima di GROUP BY.

Magari si può spostare dopo GROUP BY?

Neanche quello! Spesso bisogna filtrare le righe della tabella prima della group by. Poi si fa la group by sui dati filtrati. E poi si buttano via i dati inutili dopo la group by.

Allora perché non prendere l'operatore WHERE, copiarlo, chiamarlo HAVING e metterlo dopo GROUP BY?

Esatto, è proprio quello che facciamo! :)

Differenza tra HAVING e WHERE

WHERE filtra le righe prima della group by.

Pensa che stai scegliendo le torte in base al gusto: fragola e cioccolato — le tieni, le altre — via. Questo è il lavoro di WHERE.

HAVING filtra dopo che i dati sono stati raggruppati e le funzioni di aggregazione hanno fatto la loro magia.

Per esempio, hai già raggruppato le torte per tavolo, hai contato quante ce ne sono e ora vuoi tenere solo i tavoli dove ci sono più di tre torte.

Quindi, HAVING si usa per filtrare i dati a livello di gruppo.

Sintassi di HAVING

La sintassi è quasi uguale a quella di WHERE, ma funziona un po' diversamente:

SELECT colonne, funzioni_aggregate
FROM tabella
GROUP BY colonne
HAVING condizione;

Fasi di esecuzione:

  1. Prima le righe vengono filtrate con WHERE.
  2. Poi i dati vengono raggruppati con GROUP BY.
  3. Alle righe raggruppate si applicano le funzioni di aggregazione.
  4. Infine, il risultato viene filtrato con HAVING.

Esempi di utilizzo di HAVING

Esempio 1: Filtrare le facoltà con molti studenti

Vuoi sapere quali facoltà nell'università hanno più di 100 studenti. Supponiamo di avere la tabella students:

id name faculty
1 Alice Engineering
2 Bob Engineering
3 Charlie Arts
4 Daisy Business
5 ... ...

Query:

SELECT faculty, COUNT(*) AS student_count
FROM students
GROUP BY faculty
HAVING COUNT(*) > 100;

Cosa succede qui:

  • Prima raggruppiamo gli studenti per la colonna faculty usando GROUP BY.
  • Poi la funzione di aggregazione COUNT(*) conta quanti studenti ci sono in ogni facoltà.
  • Infine, HAVING elimina tutte le facoltà dove ci sono 100 studenti o meno.

Risultato:

faculty student_count
Engineering 150
Arts 120

Esempio 2: Reparti con stipendio medio alto

Vuoi trovare solo quei reparti dove lo stipendio medio dei dipendenti supera 50.000. Supponiamo di avere la tabella employees:

id name department salary
1 Alice IT 60000
2 Bob HR 45000
3 Charlie IT 70000
4 Daisy HR 52000
5 ... ... ...

Query:

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;

Risultato:

department avg_salary
IT 65000

Nota: HAVING lavora sui risultati che sono stati calcolati dopo GROUP BY.

Ordine di esecuzione di WHERE, GROUP BY e HAVING

Il filtraggio con WHERE e HAVING avviene in fasi diverse. Per capire meglio la differenza, vediamo il processo passo dopo passo di una query:

  1. WHERE: filtraggio delle righe.

    Qui vengono processate tutte le righe della tabella. Se una riga non passa la condizione WHERE, non viene nemmeno considerata dopo.

  2. GROUP BY: raggruppamento delle righe.

    Dopo il filtraggio, le righe vengono unite in gruppi in base alle colonne specificate in GROUP BY.

  3. Funzioni di aggregazione:

    Sui dati raggruppati si applicano funzioni come COUNT(), AVG(), SUM() ecc.

  4. HAVING: filtraggio dei gruppi.

    Qui vengono processati solo i risultati delle funzioni di aggregazione. Le condizioni HAVING si applicano solo ai gruppi.

Particolarità di HAVING

Particolarità 1: Lavorare con le funzioni di aggregazione

La differenza principale tra HAVING e WHERE è che HAVING lavora con le funzioni di aggregazione. Per esempio:

SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) > 50000;

In questa query AVG(salary) non si può usare dentro WHERE, perché WHERE lavora sulle righe prima della group by. Una query tipo:

SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;

darà errore: aggregate functions are not allowed in WHERE.

Particolarità 2: Filtraggio senza group by

Puoi usare HAVING anche senza specificare GROUP BY. In questo caso la query viene interpretata come se ci fosse un solo gruppo — tutte le righe:

SELECT AVG(salary) AS avg_salary
FROM employees
HAVING AVG(salary) > 50000;

Esempio pratico

Supponiamo di avere un negozio e la tabella delle vendite sales:

id product_id sales_amount
1 101 200.00
2 102 300.00
3 101 400.00
4 103 150.00

Query: trovare i prodotti con un totale vendite superiore a 500.

SELECT product_id, SUM(sales_amount) AS total_sales
FROM sales
GROUP BY product_id
HAVING SUM(sales_amount) > 500;

Risultato:

product_id total_sales
101 600.00

Errori tipici

Uso delle funzioni di aggregazione in WHERE:

Per esempio:

SELECT department, AVG(salary)
FROM employees
WHERE AVG(salary) > 50000
GROUP BY department;

Errore: non si possono usare funzioni di aggregazione in WHERE.

Errori con NULL:

Se i dati contengono NULL, il filtraggio può dare risultati strani. Per esempio:

SELECT department, SUM(salary)
FROM employees
GROUP BY department
HAVING SUM(salary) > 0;

Se la colonna salary contiene solo NULL, il risultato può essere zero o vuoto.

Complimenti! A questo punto puoi già filtrare i dati aggregati senza problemi! Ricorda che HAVING è la tua chiave per fare analisi a livello di gruppo, dove il solito WHERE non basta più.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION