CodeGym /Corsi /SQL SELF /Confronto tra WHERE e HAVING: analisi dell'ordine di esec...

Confronto tra WHERE e HAVING: analisi dell'ordine di esecuzione e esempi pratici

SQL SELF
Livello 8, Lezione 2
Disponibile

Dai, ripassiamo ancora una volta l’ordine di esecuzione delle operazioni in SQL, e anche con cosa può e non può lavorare WHERE e HAVING. È un punto importante, su cui poi si costruiscono un sacco di sfumature nel lavoro con le query SQL. Devi capirlo davvero bene.

Quindi, in cosa WHERE è diverso da HAVING, quando usare uno e quando l’altro, e come sono collegati tra loro? Questo ti aiuterà a non confonderti nella logica delle query e a filtrare i dati in modo efficace. Facciamo un riassunto delle nostre conoscenze su WHERE e HAVING.

Cos’è WHERE?

WHERE — è una condizione che si usa per filtrare le righe prima della group by o dell’uso di funzioni di aggregazione. Cioè, prima si selezionano dalla tabella le righe che rispettano i criteri, e solo dopo si fa la group by sui dati rimasti.

👉 Immagina di raccogliere frutta al mercato. WHERE è il filtro che ti aiuta a scartare in anticipo le mele rovinate, ancora prima di iniziare a dividerle per dimensione o colore.

Esempio:

SELECT *
FROM students
WHERE age > 18;

Questa query selezionerà tutti gli studenti con più di 18 anni prima di qualsiasi altra operazione.

Cos’è HAVING?

HAVING — è un filtro che si applica dopo la group by (GROUP BY). Ti permette di mettere condizioni sui dati raggruppati, tipo lasciare solo quei gruppi dove la media dei voti degli studenti è sopra 80.

👉 Torniamo alle mele. HAVING è il filtro che usi dopo aver già diviso le mele nei cesti (gruppi). Ora ti interessano, per esempio, solo i cesti (gruppi) dove ci sono più di dieci mele.

Esempio:

SELECT cesto, COUNT(*)
FROM mele
GROUP BY cesto
HAVING COUNT(*) > 10;

Questa query selezionerà solo quei cesti dove il numero di mele è maggiore di 10.

Differenze principali:

Caratteristica WHERE HAVING
Applicazione Filtra le righe prima della group by Filtra i gruppi dopo la group by
Uso con aggregazione Non puoi usare funzioni di aggregazione Puoi usare funzioni di aggregazione
Obiettivo Toglie le righe inutili per la group by Toglie i gruppi che non rispettano la condizione

Ordine di esecuzione di WHERE, GROUP BY e HAVING

Per capire meglio come funzionano WHERE e HAVING, vediamo l’ordine di esecuzione delle query SQL:

  1. Prima si esegue FROM, si selezionano le righe dalla tabella.
  2. Poi si applica WHERE, filtrando solo le righe che rispettano le condizioni.
  3. Dopo si fa la group by con GROUP BY. Otteniamo una nuova tabella con i dati raggruppati.
  4. Si applica HAVING, filtrando i gruppi che rispettano le condizioni.
  5. Infine, si selezionano i risultati con SELECT.

In modo schematico è così:

1. FROM → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. SELECT

Esempio:

SELECT department, AVG(age) AS avg_age
FROM students
WHERE age > 18
GROUP BY department
HAVING AVG(age) > 20;

Qui succede questo:

  1. Nella tabella students si selezionano le righe dove age > 18 (si usa WHERE).
  2. Le righe rimaste vengono raggruppate per department.
  3. Per ogni gruppo si calcola l’età media degli studenti.
  4. I gruppi dove l’età media è minore o uguale a 20 vengono esclusi con HAVING.
  5. Si mostrano i risultati.

Esempi di uso combinato

Esempio 1: Filtraggio prima e dopo la group by

Condizione: trovare i dipartimenti dove ci sono più di 5 studenti, considerando solo gli studenti con più di 18 anni.

Tabella di partenza students

id name department age gpa
1 Alex Lin ComputerSci 20 3.8
2 Maria Chi Math 22 3.5
3 Anna Song ComputerSci 19 4.0
4 Otto Art Math 17 3.9
5 Liam Park Physics 21 3.7
6 Jane Doe ComputerSci 23 3.6
7 Tom Brown Math 25 3.4
8 Sara White Math 19 3.8
9 John Smith ComputerSci 20 3.7
10 Emily Green Physics 18 3.9
11 Mark Blue ComputerSci 21 3.5
12 Zoe Black Math 22 3.6
13 Max Gray ComputerSci 20 3.9
14 Eva Gold Math 23 3.7
15 Nick Silver Physics 19 3.8

Query:

SELECT department, COUNT(*) AS student_count
FROM students
WHERE age > 18
GROUP BY department
HAVING COUNT(*) > 5;

Risultato: -- Risultato della query

department student_count
ComputerSci 6

Spiegazione:

  1. Prima togliamo le righe dove age <= 18 (condizione WHERE).
  2. Raggruppiamo i dati per dipartimento (GROUP BY department).
  3. Calcoliamo il numero di studenti in ogni gruppo.
  4. Togliamo i gruppi dove ci sono meno o uguale a 5 studenti (HAVING COUNT(*) > 5).

Esempio 2: Errore usando WHERE invece di HAVING

Condizione: trovare i dipartimenti dove l’età media è maggiore di 22 anni.

Query sbagliata:

SELECT department, AVG(age) AS avg_age
FROM students
WHERE AVG(age) > 22
GROUP BY department;

Errore: SQL non permette di usare funzioni di aggregazione AVG in WHERE, perché in quel momento gli aggregati non sono ancora calcolati.

Query corretta:

SELECT department, AVG(age) AS avg_age
FROM students
GROUP BY department
HAVING AVG(age) > 22;

Qui la condizione AVG(age) > 22 si applica dopo la group by.

Consigli pratici

Se devi filtrare le righe, usa WHERE. Esempio: trovare tutti i dipendenti con stipendio sopra 5000.

SELECT *
FROM employees
WHERE salary > 5000;

Se devi filtrare i gruppi, usa HAVING. Esempio: trovare i reparti con stipendio totale sopra 100 000.

SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department
HAVING SUM(salary) > 100000;

Combina WHERE e HAVING per condizioni più complesse.

Esempio: trovare i paesi con più di 10 milioni di abitanti, considerando solo le città con popolazione sopra 1 milione.

SELECT country, SUM(population) AS total_population
FROM cities
WHERE population > 1000000
GROUP BY country
HAVING SUM(population) > 10000000;

Errori tipici e come risolverli

Uno degli errori più comuni è confondere WHERE e HAVING. Per esempio, provare a usare una funzione di aggregazione in WHERE:

SELECT department, COUNT(*)
FROM students
WHERE COUNT(*) > 10
GROUP BY department;

Questa query darà errore, perché i calcoli di aggregazione non sono disponibili nella fase WHERE. Il modo giusto è usare HAVING:

SELECT department, COUNT(*)
FROM students
GROUP BY department
HAVING COUNT(*) > 10;

Un altro errore è scegliere condizioni sbagliate per WHERE. Per esempio:

SELECT department, AVG(age) AS avg_age
FROM students
WHERE avg_age > 20
GROUP BY department;

Qui la condizione avg_age > 20 non va bene, perché avg_age non è ancora calcolato. Soluzione: sposta questa condizione in HAVING:

SELECT department, AVG(age) AS avg_age
FROM students
GROUP BY department
HAVING AVG(age) > 20;

Spero che ora tu abbia una chiara idea di come sono diversi WHERE e HAVING, come usarli correttamente e come evitare gli errori più comuni. Queste conoscenze ti serviranno per creare report complessi, filtrare dati per l’analisi e ottimizzare le query. Insomma, per la maggior parte delle query SQL reali che scriverai :)

2
Compito
SQL SELF, livello 8, lezione 2
Bloccato
Trova i dipartimenti con più di 5 studenti di età superiore a 18 anni
Trova i dipartimenti con più di 5 studenti di età superiore a 18 anni
2
Compito
SQL SELF, livello 8, lezione 2
Bloccato
Trova i dipartimenti con l'età massima degli studenti superiore a 23 anni
Trova i dipartimenti con l'età massima degli studenti superiore a 23 anni
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION