Torna all'elenco degli articoli Articoli
Tempo di lettura: 4 minuti

HAVING vs WHERE in SQL: Cosa bisogna sapere

Questo articolo parla delle clausole WHERE e HAVING di SQL. Entrambe le clausole fanno parte delle basi del comando SQL SELECT. Hanno usi simili, ma ci sono anche importanti differenze che ogni persona che usa SQL dovrebbe conoscere. Vediamo cosa c'è dietro il dibattito HAVING vs WHERE.

In questo articolo supporremo di lavorare per un'agenzia sociale governativa che sostiene persone o famiglie il cui reddito è inferiore a una certa soglia. Questa agenzia utilizza diverse metriche per identificare le persone o le famiglie che hanno bisogno di aiuto.

Per prima cosa, esaminiamo il set di dati campione. Poi, nel resto dell'articolo, creeremo delle query basate su questo set di dati.

Set di dati di esempio

Questo dataset descrive le persone appartenenti a quattro famiglie che vivono in due città. Per semplicità, assumeremo che last_name identifichi la famiglia. L'idea è di ottenere metriche a livello di persona e di famiglia.

TABLE Persons

namelast_namebirth_dateyear_incomecity
MaryRoberts1964-01-1178000Oklahoma
PeterRoberts1962-09-2586500Oklahoma
JohnRoberts1999-06-030Oklahoma
SueRoberts1996-03-060Oklahoma
MelindaRoberts1998-04-040Oklahoma
GeorgeHudson1953-02-2348000Oklahoma
NancyHudson1958-12-0665000Oklahoma
AnnHudson1979-04-0235000Oklahoma
CarlGibson1963-04-03102800Phoenix
LiGibson1963-12-2796000Phoenix
KateBishop1994-07-10920000Phoenix
MarkBishop2018--9-130Phoenix

Ok. Ora che abbiamo visto il set di dati, iniziamo!

WHERE e HAVING: esempi semplici

In parole povere, le clausole WHERE e HAVING agiscono come filtri: rimuovono i record o i dati che non soddisfano determinati criteri dal risultato finale di una query. Tuttavia, vengono applicate a insiemi di dati diversi. Questo è il punto importante da capire su WHERE e HAVING: WHERE filtra a livello di record, mentre HAVING filtra a livello di "gruppo di record".

Vediamo alcuni esempi.

Ecco un esempio di query che utilizza la clausola WHERE: Supponiamo di voler ottenere i nomi delle persone con un reddito annuo superiore a 100.000 dollari. Dobbiamo filtrare (o scartare) a livello di record, quindi per questa query utilizzeremo la clausola WHERE invece della clausola HAVING:

Testo della query per il copia-incolla:

SELECT name, last_name
FROM  persons
WHERE year_income > 100000;

DOVE vs HAVING

Proviamo ora a fare una query simile, ma questa volta con la clausola HAVING: Supponiamo di voler ottenere last_name delle famiglie che hanno un reddito familiare (cioè la somma dei redditi di tutti i membri della famiglia) superiore a 100.000 dollari. Questo è un chiaro caso di utilizzo della clausola HAVING, poiché non è necessario filtrare per record. (Non scartiamo il record di una persona perché guadagna meno di 100.000 dollari). L'idea è quella di filtrare in base al reddito familiare, quindi è necessario raggruppare le persone per last_name e utilizzare la clausola HAVING per filtrare i gruppi di persone, come mostrato di seguito:

Testo della query per il copia-incolla:

SELECT 	last_name,
		SUM(year_income) AS "family_income"
FROM  persons
GROUP BY last_name
HAVING SUM(year_income) > 100000;

DOVE vs HAVING

CLAUSOLE HAVING COMPLESSE

Possiamo utilizzare tutte le funzioni aggregate che desideriamo nella condizione della clausola HAVING. Proseguiamo con l'analisi dei redditi familiari e calcoliamo il reddito medio per membro di ogni famiglia. Vogliamo identificare le famiglie che guadagnano meno di 50.000 a persona. Da un punto di vista economico, questa analisi può mostrare più informazioni sui redditi familiari rispetto alla precedente. Ecco la query:

Testo della query per il copia-incolla:

SELECT 	last_name, 
COUNT(*) as "members", 
SUM(year_income) as "family_income",
SUM(year_income) / COUNT(*) as "per_member_income"
FROM  persons
GROUP BY last_name
HAVING SUM(year_income)  / COUNT(*) < 50000;

DOVE vs HAVING

Nota: la clausola HAVING ha alcune restrizioni; una di queste è che le colonne a livello di record nella condizione HAVING devono comparire anche nella clausola GROUP BY.

Utilizzo di WHERE e HAVING nella stessa query SQL

È molto comune utilizzare WHERE e HAVING nella stessa query. Eseguiamo una query per ottenere il reddito familiare totale e il reddito per membro per le famiglie dell'Oklahoma con più di quattro membri:

Testo della query da copiare e incollare:

SELECT 	last_name, 
COUNT(*) as "members", 
SUM(year_income) as "family_income",
SUM(year_income) / COUNT(*) as "per_member_income"
FROM  persons
WHERE city = ‘Oklahoma’
GROUP BY last_name
HAVING COUNT(*) > 4;

DOVE vs HAVING

WHERE e HAVING nelle query complesse

Per concludere l'articolo, costruiremo una query che restituisca le famiglie con un reddito familiare inferiore al reddito medio della loro città. La parte difficile è la sottoquery che ottiene il reddito medio per una determinata città. Si noti che utilizziamo una query diversa perché si tratta del reddito medio per città; non è basato sul numero di membri per famiglia, ma sul numero di famiglie in quella città, calcolato con count(distinct last_name).

Testo della query per il copia-incolla:

SELECT
  last_name, 
  COUNT(*) AS "members", 
  SUM(year_income) AS "family_income",
  SUM(year_income) / COUNT(*) AS "per_member_income"
FROM persons p
GROUP BY last_name
HAVING SUM(year_income) < (
  SELECT 
  SUM(year_income) / COUNT(distinct last_name) 
  FROM persons 
  WHERE city = p.city
);
DOVE vs HAVING

Risolto: WHERE vs. HAVING in SQL

Abbiamo esaminato diverse query che utilizzano le clausole WHERE e HAVING di SQL. Come abbiamo detto, entrambe le clausole funzionano come filtri, ma ciascuna si applica a un livello di dati diverso. La clausola WHERE filtra a livello di record, mentre la clausola HAVING filtra a livello di gruppo.

L'SQL è un linguaggio estremamente flessibile e si possono creare milioni di combinazioni utilizzando le clausole WHERE e HAVING. A questo punto, vorrei citare un ottimo corso relativo agli argomenti trattati in questo articolo: LearnSQL's Creating Basic SQL Reports in SQL. È utile a chi conosce le basi di SQL e desidera migliorare le proprie competenze nella creazione di report SQL significativi. Andate oltre - esplorate SQL!