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

Come usare GROUP BY in SQL

In questo articolo vi forniremo una guida passo passo all'uso di GROUP BY in SQL. Scoprite le sfumature del GRUPPO PER e scoprirete i diversi modi di utilizzarla.

GROUP BY è una delle clausole più utilizzate in SQL. Essa consente di passare dalla semplice selezione dei dati dal database al raggruppamento delle righe con gli stessi valori di colonna in un unico gruppo. Se utilizzato con le funzioni aggregate di SQL, GROUP BY permette di calcolare metriche come il conteggio del numero di istanze o la ricerca del valore totale, medio, minimo o massimo.

GROUP BY fa parte delle conoscenze di base di SQL; è necessario sentirsi a proprio agio con esso prima di passare a concetti più complicati.

Sapete già che la scrittura del codice si impara meglio con la pratica. Trovare l'opportunità di scrivere codice SQL regolarmente potrebbe essere difficile se non si lavora quotidianamente con SQL. Difficile, ma non impossibile. Ciò che lo rende possibile è il Esercizi SQL corso. Le esercitazioni offrono molte opportunità di esercitarsi con GROUP BY e altri concetti SQL, come le funzioni aggregate, le JOIN e le subquery.

Come funziona il GROUP BY? Un esempio

Utilizzerò la tabella typewriter_products per dimostrare l'importanza della clausola GROUP BY in SQL. La tabella mostra le cose che si possono acquistare da un'azienda fittizia che vende prodotti legati alle macchine da scrivere. Per chi se lo chiedesse, questa è una macchina da scrivere:

Come usare GROUP BY in SQL

Fonte: https://i.etsystatic.com/8429430/r/il/132716/1789166606/il_fullxfull.1789166606_1qnc.jpg

Quasi come un computer senza schermo. Chissà quanti libri importanti sono stati scritti con la macchina da scrivere. I libri, ve li ricordate?

(Ma basta con l'autocompiacimento, parliamo del tavolo).

Sì, la tabella. Ha le seguenti colonne:

  • id - L'ID univoco del record.
  • product_name - Il nome del prodotto.
  • product_id - L'ID del prodotto.
  • ribbon_brand - La marca del nastro della macchina da scrivere.
  • typewriter_brand - La marca della macchina da scrivere per cui è stato creato il nastro.
  • ribbon_color - Il colore del nastro per macchina da scrivere.
  • units - Il numero di unità disponibili del prodotto.
  • price - Il prezzo unitario del prodotto.

I dati sono mostrati di seguito.

idproduct_nameproduct_idribbon_brandtypewriter_brandribbon_colorunitsprice
1typewriter ribbon1All You NeedOlympiaBlack8810.00
2typewriter ribbon1All You NeedOlympiaBlack + Red4810.00
3typewriter ribbon2Ribbons & UsOlympiaBlack9712.39
4typewriter ribbon2Ribbons & UsOlympiaBlack + Red14715.15
5typewriter ribbon3All You NeedUnderwoodBlack1424.74
6typewriter ribbon3All You NeedUnderwoodBlack + Red1325.17
7typewriter ribbon4Our RibbonUnderwoodBlack5425.00
8typewriter ribbon5Ribbons & UsUnderwoodBlack15730.47
9typewriter ribbon5Ribbons & UsUnderwoodBlack + Red1428.47
10typewriter ribbon6All You NeedAdlerBlack4420.00
11typewriter ribbon6All You NeedAdlerBlack + Red1630.00
12typewriter ribbon7Ribbons & UsAdlerBlack5424.69
13typewriter ribbon7Ribbons & UsAdlerBlack + Red2730.30

Con questa tabella si possono ottenere diversi gruppi. Ad esempio, è possibile calcolare il prezzo medio di un prodotto in base alla marca della macchina da scrivere.

Ecco la query che permette di farlo:

SELECT typewriter_brand,
 AVG(price) AS average_price
FROM typewriter_products
GROUP BY typewriter_brand;

Questa query raggruppa i dati in base alla marca della macchina da scrivere e calcola il prezzo medio. La query produce questa tabella:

typewriter_brandaverage_price
Adler26.25
Olympia11.89
Underwood26.77

L'output mostra tre tipi di marche di macchine da scrivere e il prezzo medio di ogni macchina.

Oppure si può trovare il numero di nastri disponibili per colore con questa query:

SELECT ribbon_color,
	 SUM(units) AS sum_units
FROM typewriter_products
GROUP BY ribbon_color;

Il gruppo in questa query è il colore del nastro. Uso anche la funzione aggregata SUM() per sommare il numero di unità per colore di nastro. Ecco il risultato:

ribbon_colorsum_units
Black508
Black + Red265

I dati sono raggruppati in due righe: nastro nero e nastro nero + rosso. Per ogni colore di nastro, c'è un numero di unità disponibili per la vendita.

Questa è un'anticipazione di ciò che fa GROUP BY e del suo funzionamento. Come si può vedere, la sintassi GROUP BY è relativamente semplice. Se avete bisogno di ulteriori chiarimenti sulla sintassi GROUP BY, date un'occhiata a questo articolo.

Come si possono scrivere le proprie query e utilizzare la clausola GROUP BY? Ecco alcuni suggerimenti per aiutarvi.

Come usare la clausola GROUP BY

Come si usa la clausola GROUP BY in SQL? In questa sezione vi fornirò una ricetta passo per passo. Immaginiamo di voler trovare il numero di record per ogni prodotto.

Ilprimo passo per scrivere una query dovrebbe essere quello di trovare una colonna di raggruppamento adeguata. In questo caso, si tratta di product_id. Questa colonna viene inserita nella clausola GROUP BY:

SELECT
…
GROUP BY product_id;

Ilsecondo passo è scegliere la funzione aggregata giusta e utilizzarla nell'istruzione SELECT. Poiché il nostro obiettivo è trovare il numero di record, usiamo la funzione COUNT(). Naturalmente, è necessario specificare la colonna nella clausola FROM:

SELECT COUNT(*)
FROM typewriter_products
GROUP BY product_id;

Questa query verrà eseguita? Certo! Restituirà questo risultato.

count
2
2
1
2
2
2
2

Come si può vedere, non è molto utile. Tutti i prodotti hanno due record, tranne uno, ma quali sono questi prodotti? Non ne abbiamo idea!

Ecco perché il terzo passo è importante. In questo passo, scrivere anche la colonna di raggruppamento in SELECT:

SELECT product_id,
	 COUNT(*)
FROM typewriter_products
GROUP BY product_id
ORDER BY product_id; 

Ora la query mostrerà questo risultato.

product_idcount
12
22
32
41
52
62
72

È molto più utile, vero? Ora sapete che il prodotto con ID 4 ha una sola occorrenza nella tabella. Probabilmente avrete notato che ho usato COUNT(*) nelle query precedenti. Questo non è l'unico modo per utilizzare la funzione aggregata. È anche possibile conoscere tutte le opzioni di utilizzo di COUNT().

Confrontando le due query precedenti, si può notare che è possibile utilizzare una colonna in GROUP BY ma non in SELECT; il raggruppamento funziona comunque.

E se si utilizzasse la colonna nell'istruzione SELECT ma non in GROUP BY? No, non è possibile. La regola generale è: Se la colonna è presente in SELECT e non è utilizzata in una funzione aggregata, deve essere elencata nella clausola GROUP BY. Ecco ulteriori dettagli su questa regola.

Altri suggerimenti per l'uso di GROUP BY in SQL

Sebbene l'uso della clausola GROUP BY sembri piuttosto semplice (e lo è!), esistono altri suggerimenti e trucchi che ne renderanno l'uso molto più confortevole.

Utilizzare un identificatore univoco

Quando si sceglie la colonna per cui raggruppare, in genere si dovrebbe usare la colonna che identifica in modo univoco il gruppo. In caso contrario, il risultato potrebbe essere fuorviante o semplicemente sbagliato.

Ad esempio, mostriamo i prodotti per marca di macchina da scrivere, ma proviamo a raggruppare i dati per nome del prodotto. La query ...

SELECT product_name,
	 typewriter_brand,
	 COUNT(*) AS product_count
FROM typewriter_products
GROUP BY product_name, typewriter_brand
ORDER BY typewriter_brand;

... produrrà la seguente tabella:

product_nametypewriter_brandproduct_count
typewriter ribbonAdler4
typewriter ribbonOlympia4
typewriter ribbonUnderwood5

Se si raggruppassero i dati in questo modo, si avrebbe l'impressione errata che ci sia un solo prodotto per ciascuna delle tre marche di macchine da scrivere: un prodotto che compare quattro volte per le macchine da scrivere Adler e Olympia e cinque volte per Underwood.

E se si utilizzasse la colonna product_id invece di nome_prodotto?

SELECT product_id,
	 typewriter_brand,
	 COUNT(*) AS product_count
FROM typewriter_products
GROUP BY product_id, typewriter_brand
ORDER BY typewriter_brand;

Il risultato è leggermente diverso:

product_idtypewriter_brandproduct_count
6Adler2
7Adler2
1Olympia2
2Olympia2
3Underwood2
4Underwood1
5Underwood2

Ci sono ancora prodotti per tre marche di macchine da scrivere. Tuttavia, ora si sa che ci sono due prodotti per Adler e Olympia, entrambi presenti due volte per ogni macchina da scrivere. Ci sono tre prodotti per Underwood. Non solo, ma si sa anche di quali prodotti si tratta.

Guardiamo questo esempio:

SELECT product_id,
	 product_name,
	 typewriter_brand,
	 COUNT(*) AS product_count
FROM typewriter_products
GROUP BY product_id, product_name, typewriter_brand
ORDER BY typewriter_brand;

Si tratta di una versione estesa della query precedente. Raggruppiamo nuovamente per product_id. Per ottenere il numero di occorrenze di prodotti, utilizziamo la funzione COUNT(). Vogliamo anche altre etichette, quindi aggiungiamo alla SELECT il nome del prodotto e la marca della macchina da scrivere.

Poiché queste colonne compaiono nella SELECT, devono comparire anche in GROUP BY. Si noti che tutte le colonne lo fanno, tranne quella con la funzione aggregata.

Osservate l'output:

product_idproduct_nametypewriter_brandproduct_count
6typewriter ribbonAdler2
7typewriter ribbonAdler2
1typewriter ribbonOlympia2
2typewriter ribbonOlympia2
3typewriter ribbonUnderwood2
4typewriter ribbonUnderwood1
5typewriter ribbonUnderwood2

Si può notare che questo output fornisce il quadro più chiaro. Ci sono sette prodotti diversi, ma sono tutti nastri per macchine da scrivere. Questi prodotti sono per tre marche di macchine da scrivere. Tutti i prodotti hanno due occorrenze, tranne il prodotto #4.

Raggruppamento per valore

Non è sempre necessario raggruppare in base alla colonna ID. È anche possibile raggruppare i dati per valore.

Ad esempio, se si volesse sapere quante unità ci sono in base al colore del nastro, si potrebbe usare questa query:

SELECT ribbon_color,
	 SUM(units) AS units_sum
FROM typewriter_products
GROUP BY ribbon_color;

Qui utilizziamo il colore del nastro come criterio di raggruppamento. La funzione aggregata SUM() totalizzerà le unità nel modo seguente:

ribbon_colorunits_sum
Black508
Black + Red265

L'output mostra che ci sono 508 nastri neri e 265 nastri neri e rossi.

Se non avete familiarità con la somma dei valori, date un'occhiata alla funzione SUM(). Anche le funzioni MIN() e MAX() sono comunemente utilizzate con GROUP BY.

Due colonne come definitore del gruppo

La clausola GROUP BY consente di raggruppare i dati in base a due o più colonne. Ma è anche possibile utilizzare due colonne come identificatore unico di un gruppo. Per esempio:

SELECT ribbon_color,
	 typewriter_brand,
	 SUM(units) AS units_sum
FROM typewriter_products
GROUP BY ribbon_color, typewriter_brand
ORDER BY typewriter_brand;

In questa query, utilizziamo le colonne ribbon_color e typewriter_brand per definire un gruppo. Ogni colore di nastro per una specifica macchina da scrivere sarà mostrato solo una volta. Per questo gruppo definito, si calcola il numero di nastri disponibili:

ribbon_colortypewriter_brandunits_sum
BlackAdler98
Black + RedAdler43
BlackOlympia185
Black + RedOlympia195
BlackUnderwood225
Black + RedUnderwood27

Raggruppamento in base a un'espressione

Invece di raggruppare solo per colonne, è possibile raggruppare i dati in base a un'espressione.

Vediamo la seguente query:

SELECT ribbon_brand,
	 ribbon_color,
	 units*price AS product_value,
 SUM(units*price) AS product_value_sum
FROM typewriter_products
GROUP BY ribbon_brand, ribbon_color, units*price
ORDER BY ribbon_brand;

Qui selezioniamo la marca e il colore del nastro. Inoltre, calcoliamo il valore di ciascun gruppo moltiplicando l'unità per il prezzo.

Poi raggruppiamo i dati in base alle colonne ribbon_brand e ribbon_color. Si tratta di un'operazione a cui si è già abituati. Ma aggiungiamo anche la formula per il calcolo del valore alla clausola GROUP BY. Vogliamo mostrare solo i valori unici per marca e colore del nastro. Se ci sono più valori calcolati uguali all'interno dello stesso gruppo, verranno mostrati come un'unica riga.

Per rendere più evidente l'aggregazione, ho aggiunto la somma dei valori dei prodotti. Presto capirete perché.

ribbon_brandribbon_colorproduct_valueproduct_value_sum
All You NeedBlack346.36346.36
All You NeedBlack880.001,760.00
All You NeedBlack + Red327.21327.21
All You NeedBlack + Red480.00960.00
Our RibbonBlack1,350.001,350.00
Ribbons & UsBlack1,201.831,201.83
Ribbons & UsBlack1,333.261,333.26
Ribbons & UsBlack4,783.794,783.79
Ribbons & UsBlack + Red398.58398.58
Ribbons & UsBlack + Red818.10818.10
Ribbons & UsBlack + Red2,227.052,227.05

Potrebbe sembrare che questa tabella non sia affatto raggruppata. Ma diamo un'occhiata più da vicino. Se i dati non fossero stati raggruppati, il marchio All You Need sarebbe apparso sei volte, come Ribbons & Us. Invece compare solo quattro volte. Perché? Perché i valori 880,00 e 480,00 compaiono due volte ciascuno, quindi sono raggruppati.

Questo è quanto indica la colonna product_value_sum nelle righe colorate. Queste sono le uniche righe in cui questa colonna è diversa da product_value. La riga verde ha una somma di 1.760,00 perché il valore 880,00 compare due volte. La somma della riga rossa è 960,00 perché 480,00 compare due volte.

Passi per la scrittura di una query con le funzioni GROUP BY e aggregate

Il GRUPPO BY è già stato acquisito attraverso la scrittura delle query precedenti. Ma ritengo che valga la pena di inserire questo punto in un elenco separato: la lista di controllo dei passaggi.

  • Fase 1: identificare la colonna o le colonne di raggruppamento, cioè la colonna o le colonne in base alle quali si desidera raggruppare i dati. Dopo averla identificata, inserirla nella clausola GROUP BY.
  • Fase 2: a seconda della metrica che si desidera calcolare, scegliere la funzione aggregata appropriata e utilizzarla nell'istruzione SELECT.
  • Fase 3: utilizzare la colonna di raggruppamento nell'istruzione SELECT. In questo modo si otterranno le etichette dei dati per ogni gruppo e non solo l'output della funzione aggregata.

Nessun utente SQL può evitare di usare GROUP BY

Nessun utente SQL a me noto è riuscito a vivere una vita SQL di successo e a scrivere query senza GROUP BY. È impossibile! Quindi perché non esercitarsi con GROUP BY e altre espressioni e funzioni SQL? La scelta più saggia sarebbe il nostro Esercizi SQL. Vi offre l'opportunità di esercitarvi in tutti i diversi modi di usare GROUP BY trattati nell'articolo.

Altre risorse utili per gli esempi di GROUP BY sono disponibili sul nostro blog; il concetto compare spesso anche nelle domande dei colloqui di lavoro in SQL.