back to top

SQL GROUP BY, HAVING e le funzioni di aggregazione

Le funzioni di aggregazione effettuano un calcolo all’interno di un set di valori e restituiscono un singolo valore (un unico record): sono dette di aggregazione appunto perché "aggregano" più record per trarne uno.

Le funzioni di aggregazione vengono utilizzate di frequente con le clausole GROUP BY e HAVING che consentono, appunto, di aggregare i risultati secondo alcuni criteri che vedremo di seguito.

Le funzioni di aggregazione

Di seguito l’elenco delle funzioni di aggregazione di SQL:

Funzione Descrizione
AVG() Restituisce la media tra più valori nella stessa colonna
COUNT() Restituisce un intero che indica il numero di record selezionati
MAX() Restituisce il valore massimo tra più valori nella stessa colonna
MIN() Restituisce il valore minimo tra più valori nella stessa colonna
SUM() Restituisce la somma tra più valori nella stessa colonna

Nell’utilizzo di una funzione di aggregazione è importante (consigliato, anche se non obbligatorio) specificare un alias per il risultato, con l’utilizzo della clausola AS. I nostri alias si chiameranno, per convenzione, temp (che utilizzo in genere per definire un valore temporaneo).

AVG()

La funzione AVG (dall’inglese Average) calcola la media aritmetica dei valori numerici contenuti in una data colonna. La funzione ignora i valori di tipo NULL eventualmente presenti nella colonna. Vediamo un esempio:

/* Restituisce la media del prezzo di tutti i libri trovati */
SELECT AVG(prezzo) AS temp FROM libri

COUNT()

La funzione COUNT è utilizzata per contare il numero di righe presenti in una tabella o in una selezione (se è utilizzata una clausola WHERE). La funzione prevede come argomento il nome di una colonna oppure il simbolo asterisco (*): nel primo caso i valori NULL non vengono considerati, nel secondo caso sì e vengono conteggiate tiutte le righe a prescidere che il loro valore sia NULL o meno. Vediamo un esempio:

/* Restituisce il numero di libri presenti nella tabella */
SELECT COUNT(*) AS temp FROM libri

La funzione COUNT() può essere utilizzata congiuntamente a DISTINCT per ottenere il numero dei "valori diversi" presenti nella colonna specificata:

/* Restituisce il numero di autori che hanno almeno un libro nella nostra biblioteca */
SELECT COUNT(DISTINCT(id_autore)) AS temp FROM libri

MAX() e MIN()

Le funzioni MIN e MAX restituiscono, rispettivamente, il valore minimo e il valore massimo tra i valori di una data colonna. Entrambe le funzioni ignorano i valori NULL. Vediamo alcuni esempi:

/* Restituisce il prezzo del libro più costoso */
SELECT MAX(prezzo) AS temp FROM libri;

/* Restituisce il prezzo del libro meno costoso */
SELECT MIN(prezzo) AS temp FROM libri;

SUM()

La funzione SUM restituisce la somma di tutti i valori (di tipo numerico) contenuti in una data colonna. Qualora nella colonna siano presenti valori NULL questi verranno considerati come 0. Vediamo un esempio:

/* Restituisce la somma dei prezzi di tutti i libri */
SELECT SUM(prezzo) AS temp FROM libri

La clausola GROUP BY

La clausola GROUP BY di SQL è utilizzata nelle operazioni di SELECT al fine di raggruppare i valori identici presenti in una o più colonne.

La clausola GROUP BY è un’accessorio facoltativo di SELECT e va inserita dopo FROM o WHERE (se presente). La sua sintassi è la seguente:

SELECT colonna1, colonna2, ...
FROM nome_tabella
WHERE condizione
GROUP BY colonna1, colonna2, ...

Nella sua forma di utilizzo più semplice la clausola GROUP BY produce un risultato analogo a SELECT DISTINCT. Vediamo un esempio supponendo di voler mostrare un elenco dei diversi cognomi dei contatti presenti in una ipotetica rubrica:

SELECT cognome
FROM rubrica
GROUP BY cognome
ORDER BY cognome ASC;

Il risultato di questa query è identico a quello che si otterebbe con:

SELECT DISTINCT cognome
FROM rubrica
ORDER BY cognome ASC;

La clausola HAVING

Decisamente più interessante è il funzionamento di GROUP BY quando utilizzato in congiunzione alla clausola HAVING la quale consente di impostare un filtro sui valori raggrupati. Supponiamo, volendo fare un esempio, di dover lavorare sulla tabella "ordini" di un ipotetico sito di e-commerce così strutturata:

  • id
  • cliente
  • prodotto
  • prezzo

Supponiamo ora di voler estrarre da questa tabella l’elenco dei clienti che hanno speso più di 1.000 Euro:

SELECT id_cliente, SUM(prezzo) AS spesa
FROM ordini
GROUP BY id_cliente
HAVING spesa >= 1000;

Ovviamente possiamo realizzare con HAVING anche condizioni complesse utilizzando i classici operatori AND e OR tipici della clausola WHERE, ad esempio possiamo decidere di visualizzare solo i clienti che hanno speso almeno 1000 euro oppure hanno effettuato almeno 3 acquisti:

SELECT id_cliente, SUM(id) AS acquisti, SUM(prezzo) AS spesa
FROM ordini
GROUP BY id_cliente
HAVING spesa >= 1000 OR acquisti >= 3;

L’utilizzo congiunto della clausola ORDER BY, HAVING e delle funzioni di aggregazione è estremamente utile nella creazione di report tuttavia il suo ambito di utilizzo non si limita a questa esigenza ma abbraccia molteplici esigenze di sviluppo.

Pubblicità
Massimiliano Bossi
Massimiliano Bossi
Stregato dalla rete sin dai tempi delle BBS e dei modem a 2.400 baud, ho avuto la fortuna di poter trasformare la mia passione in un lavoro (nonostante una Laurea in Giurisprudenza). Adoro scrivere codice e mi occupo quotidianamente di comunicazione, design e nuovi media digitali. Orgogliosamente "nerd" sono il fondatore di MRW.it (per il quale ho scritto centinaia di articoli) e di una nota Web-Agency (dove seguo in prima persona progetti digitali per numerosi clienti sia in Italia che all'estero).