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

Come usare WHERE con GROUP BY in SQL

In questo articolo, discuteremo di come combinare le clausole WHERE e GROUP BY in SQL. Se scrivete SQL quotidianamente, vi renderete subito conto della frequenza con cui vengono utilizzate le clausole WHERE e GROUP BY. WHERE è una parte essenziale della maggior parte delle query. Permette di filtrare grandi insiemi di dati per ottenere solo le parti che interessano. GROUP BY è uno degli strumenti più potenti di cui dispone un analista quando aggrega i dati. Alla fine di questo articolo, capirete come utilizzare efficacemente entrambe le clausole, evitando le insidie più comuni.

Quando si tratta di scrivere SQL, considerate ogni clausola (SELECT, WHERE, GROUP BY, ecc.) come uno strumento separato. Man mano che si impara la sintassi SQL, si aggiunge quello strumento al proprio kit di strumenti. Come potete immaginare, un meccanico con pochi strumenti non sarà molto efficace. Non vi consiglio di portare la vostra auto da qualcuno che ha solo una manciata di strumenti. Lo stesso vale per l'analisi dei dati. Più strumenti si hanno a disposizione, più velocemente ed efficacemente si possono analizzare diversi set di dati.

Uno dei modi più completi per acquisire gli strumenti SQL è seguire il nostro corso interattivo SQL per principianti. Il corso contiene 129 esercizi e copre le competenze SQL di base e intermedie, fornendovi tutto ciò che vi serve per diventare un analista di dati efficace.

Cominciamo a dare un'occhiata approfondita a WHERE e GROUP BY separatamente. Dopo aver acquisito queste conoscenze di base, combineremo i due argomenti e scateneremo tutta la loro potenza.

La clausola WHERE

Come detto in precedenza, la clausola WHERE viene utilizzata per filtrare un insieme di dati e restituire solo i record che corrispondono a determinati criteri. Consideriamo il seguente set di dati, che include le popolazioni dei Paesi per il 2022.

A scopo illustrativo, diremo che questi dati sono contenuti in una tabella chiamata world_populations e comprendono solo i 10 paesi più popolosi. Esaminiamo questi dati eseguendo:

SELECT *
FROM world_populations

Ecco il risultato:

countrypopulationyearly_changenet_changemed_ageurban_pop_pctworld_share
China1,439,323,7760.00395,540,09038.61.1847
India1,380,004,3850.009913,586,63128.35.1770
United States331,002,6510.00591,937,73438.83.0425
Indonesia273,523,615.01072,898,04730.56.0351
Pakistan220,892,340.024,327,02223.35.0283
Brazil212,559,41700721,509,89033.88.0273
Nigeria206,139,589.02585,175,99018.52.0264
Bangladesh164,689,383.01011,643,22228.39.0211
Russia145,934,462.000462,20640.74.0187
Mexico128,932,753.01061,357,22429.84.0165

OK, abbiamo i nostri dati. Ora aggiungiamo alcuni filtri.

Esempio #1

Nel nostro primo esempio, vogliamo vedere solo i Paesi con una popolazione superiore a 200 milioni. Per farlo, eseguiamo la seguente query:

SELECT *
FROM world_populations
WHERE population > 200000000

E il risultato:

countrypopulationyearly_changenet_changemed_ageurban_pop_pctworld_share
China14393237760.0039554009038.61.1847
India13800043850.00991358663128.35.1770
United States3310026510.0059193773438.83.0425
Indonesia273523615.0107289804730.56.0351
Pakistan220892340.02432702223.35.0283
Brazil2125594170.72%15098903388%2.73%
Nigeria2061395892.58%51759901852%2.64%

Possiamo vedere che la clausola WHERE ha filtrato Bangladesh, Russia e Messico perché le loro popolazioni sono al di sotto della soglia stabilita nella nostra query.

Esempio #2

Anche la clausola WHERE può supportare più filtri. Elenchiamo solo i Paesi che hanno registrato una variazione annuale positiva nel numero di migranti e in cui almeno l'80% della popolazione vive in aree urbane. Si noti che abbiamo usato AND nella clausola WHERE per collegare queste due condizioni:

SELECT *
FROM world_populations
WHERE migrants > 0
  AND urban_pop_pct > .80

Questa query restituisce:

countrypopulationyearly_changenet_changemed_ageurban_pop_pctworld_share
United States3310026510.0059193773438.83.0425
Brazil2125594170.0072150989033.88.0273

Non c'è limite alla quantità di filtri che si possono fare in una clausola WHERE. Per maggiori dettagli, consultate la nostra Guida completa alla clausola WHERE di SQL.

La clausola GROUP BY

Per comprendere GROUP BY, utilizzeremo un altro set di dati chiamato transactions. Esso contiene i dati transazionali di un rivenditore online:

DescriptionProductCategoryQuantityUnitPriceCustomerID
KNITTED UNION FLAG HOT WATER BOTTLEKitchen63.3917850
POPPY'S PLAYHOUSE BEDROOMToys62.117850
IVORY KNITTED MUG COSYKitchen61.6513047
BOX OF VINTAGE JIGSAW BLOCKSToys34.9513047
RED COAT RACK PARIS FASHIONClothing34.9513047
YELLOW COAT RACK PARIS FASHIONClothing34.9513047
BLUE COAT RACK PARIS FASHIONClothing34.9513047

Esempio #1

L'operatore GROUP BY viene utilizzato per aggregare i dati raggruppando i record che condividono lo stesso valore in un campo specifico. Per rispondere alla domanda "Quanti articoli sono stati venduti in ciascuna categoria di prodotti?", si deve eseguire la seguente query:

SELECT 
  productCategory,
  SUM(quantity) as quantity
FROM transactions 
GROUP BY productCategory

Ecco i risultati:

ProductCategoryQuantity
Kitchen12
Toys9
Clothing9

Ci sono due prodotti nella categoria prodotti da cucina: BOTTIGLIA DELL'ACQUA CALDAIA CON BANDIERA DELL'UNIONE A MAGLIA e COSA DELLA TAZZA A MAGLIA IN AVORIO. Ognuno di questi prodotti ha una quantità pari a 6; pertanto, la somma totale per la categoria di prodotti da cucina è pari a 12.

Ci sono due prodotti nella categoria dei giocattoli. POPPY'S PLAYHOUSE BEDROOM ha una quantità di 6 e BOX OF VINTAGE JIGSAW BLOCKS ha una quantità di 3, per un totale di 9. Infine, ci sono tre prodotti nella categoria dei prodotti da cucina.

Infine, ci sono tre prodotti nella categoria abbigliamento, ciascuno con una quantità di 3. Questo porta la somma totale della categoria abbigliamento a 9.

Non li analizzeremo tutti, ma ci sono molti tipi di aggregazioni a disposizione dell'analista di dati. Questi includono SUM(), AVG(), COUNT(), MEDIAN(), MIN() e MAX(). Ulteriori informazioni sono disponibili nell'articolo Come utilizzare le funzioni aggregate nella clausola WHERE.

Esempio #2

E se volessimo aggregare le quantità per ogni categoria di prodotto e per ogni cliente? Possiamo GROUP BY più colonne:

SELECT 
  customerId,
  productCategory,
  SUM(quantity) as quantity
FROM transactions 
GROUP BY customerId, productCategory

E questo è il risultato:

CustomerIDProductCategoryQuantity
17850Kitchen6
17850Toys6
13047Kitchen6
13047Toys3
13047Clothing9

Possiamo vedere che c'è una riga per ogni combinazione di cliente e categoria di prodotto; ora sappiamo quanti articoli di ogni categoria ha acquistato ogni cliente.

Per ulteriori informazioni su GROUP BY, consultare Utilizzo di GROUP BY in SQL e GROUP BY in SQL spiegato.

Usare WHERE e GROUP BY insieme

Ora che abbiamo gettato le basi, combiniamo insieme WHERE e GROUP BY. È importante ricordare che la clausola WHERE filtrerà il set di dati prima che la clausola GROUP BY venga valutata. Inoltre, la clausola WHERE deve sempre precedere GROUP BY. Se viene inserita dopo, la query restituirà un errore.

Esempio n. 1

Consideriamo lo stesso set di dati e pensiamo a come rispondere alla domanda "Qual è il prezzo medio unitario dei prodotti da cucina e dei giocattoli?".

Per prima cosa dobbiamo filtrare per i prodotti da cucina e i giocattoli. Quindi, calcoleremo il prezzo medio unitario. Ecco la query:

SELECT
  productCategory,
  AVG(UnitPrice) as AvgUnitPrice
FROM transactions 
WHERE productCategory in(‘Kitchen’, ‘Toys’)
GROUP BY productCategory

E il risultato è:

ProductCategoryAvgUnitPrice
Kitchen2.52
Toys3.05

Il prezzo medio unitario viene calcolato solo per i prodotti di cucina e giocattoli. Tutte le altre categorie sono filtrate dalla ricerca.

Esempio n. 2

Consideriamo ora come ottenere la quantità totale di prodotti per categoria in cui il prezzo medio unitario è superiore a 3. A tale scopo, eseguiremo:

SELECT
  productCategory,
  SUM(quantity) as quantity
FROM transactions 
WHERE unitPrice > 3
GROUP BY productCategory

In questo esempio, gli aggregati vengono calcolati sulle righe filtrate. Il risultato è il seguente:

ProductCategoryQuantity
Kitchen6
Toys3
Clothing9

Poiché solo i prodotti BOTTIGLIA DI ACQUA CALDAIA CON BANDIERA DELL'UNIONE A MAGLIA, SCATOLA DI BLOCCHI DI MAGLIERIA D'EPOCA, PORTA CAPI ROSSO, PORTA CAPI GIALLO e PORTA CAPI BLU hanno prezzi unitari superiori a 3, questi sono gli unici prodotti inclusi nell'aggregazione.

Se escludessimo la clausola WHERE, otterremmo i seguenti risultati:

ProductCategoryQuantity
Kitchen12
Toys9
Clothing9

Qui vediamo che le quantità di tutti i prodotti, indipendentemente dal prezzo unitario, vengono totalizzate. La quantità totale è diversa per tutti i prodotti rispetto a quella dei prodotti con un prezzo unitario superiore a 3.

Esempio n. 3

E se volessimo filtrare in base a una colonna aggregata? Questo è il compito della clausola HAVING. Non è possibile inserire un'aggregazione nella clausola WHERE. La clausola HAVING viene utilizzata al posto di WHERE quando si vuole filtrare in base a funzioni aggregate. Possiamo illustrare questo punto con un altro esempio. Continuiamo con l'esempio precedente e filtriamo i risultati in base alle categorie di prodotti il cui prezzo medio unitario è superiore a 3. Per ottenere questo risultato, scriveremo:

SELECT
  productCategory 
  AVG(UnitPrice) as AvgUnitPrice
FROM transactions 
WHERE productCategory in (‘Kitchen’, ‘Toys’)
GROUP BY productCategory
HAVING AVG(UnitPrice) > 3

Risultato:

ProductCategoryAvgUnitPrice
Toys3.05

La prima cosa che accade è che la clausola WHERE limita i dati alle sole categorie di cucine e prodotti. La clausola GROUP BY aggrega poi il prezzo medio unitario per ogni categoria. Infine, la clausola HAVING filtra ulteriormente i risultati per includere solo le categorie di prodotti con un prezzo unitario medio superiore a 3.

Se si rimuovesse la clausola HAVING, si vedrebbero nel risultato sia la categoria cucina che quella giocattoli. Tuttavia, poiché il prezzo medio unitario degli articoli da cucina è inferiore a 3, viene filtrato quando si aggiunge la clausola HAVING.

Per ulteriori esempi, leggete il nostro articolo su HAVING e WHERE in SQL.

WHERE e GROUP BY: dove andare a parare?

Ottimo lavoro! Avete acquisito le conoscenze fondamentali necessarie per combinare le clausole WHERE e GROUP BY in SQL. Vi è stata presentata la differenza tra WHERE e HAVING. Ma soprattutto, potete combinare tutte e tre le clausole per filtrare e aggregare i dati in base alle vostre esigenze.

Avete aggiunto altri due strumenti al vostro kit di strumenti e siete pronti a usarli. Un ottimo modo per rafforzare queste nozioni è quello di seguire il nostro corso interattivo SQL per principianti. La pratica rende perfetti!

Inoltre, non dimenticate di dare un'occhiata a tutti gli altri nostri fantastici articoli.