Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

GROUP BY e funzioni di aggregazione

Conoscere la clausola GROUP BY di SQL e le principali funzioni di aggregazione che possono essere utilizzate con essa.
Conoscere la clausola GROUP BY di SQL e le principali funzioni di aggregazione che possono essere utilizzate con essa.
Link copiato negli appunti

Con la parola chiave DISTINCT, nella lezione 10, abbiamo visto la forma più semplice di aggregazione: quella che distingue le righe uguali riportandole quindi una sola volta. L’esempio ivi riportato è, infatti, riscrivibile utilizzando la clausola GROUP BY; in altre parole, le seguenti due istruzioni sono equivalenti:

SELECT DISTINCT surname FROM Person

SELECT surname FROM Person GROUP BY surname

Se le eseguiamo nel nostro database di esempio, otteniamo dunque gli stessi risultati. La clausola GROUP BY serve a specificare quali sono i campi su cui effettuare i raggruppamenti: il motore di query, per ogni riga esaminerà tali campi e la classificherà nel gruppo corrispondente. Si possono specificare calcoli da effettuare per ogni gruppo. Ad esempio la query seguente restituisce, per ogni gruppo (surname), il numero di occorrenze trovate, cioè quante persone hanno quel cognome:

SELECT surname, COUNT(*)
FROM Person
GROUP BY surname

In questo caso il motore raggruppa le righe in base al cognome, e per ogni gruppo effettua il conteggio di quanti elementi sono presenti nel gruppo.

Da quanto detto, possiamo desumere una naturale limitazione di SQL: se viene specificata una clausola GROUP BY, allora nella clausola SELECT deve esserci:

  • o un campo specificato nella clausola GROUP BY;
  • oppure una funzione di aggregazione.

Questo perché quando il motore aggrega le righe deve sapere come comportarsi per ogni campo da restituire.

Funzioni di aggregazione

Le funzioni di aggregazione sono particolari funzioni che operano su più righe. In generale, non tutti i database supportano le stesse funzioni, per cui è bene riferirsi alle guide ufficiali. Ad esempio MySql fornisce la funzione GROUP_CONCAT, che non è invece supportata su Oracle.

Le funzioni più comuni sono:

  • COUNT per effettuare conteggi nel gruppo;
  • SUM per le somme;
  • MAX e MIN;
  • AVG per calcolare la media.

La funzione COUNT

Questa funzione può essere invocata in tre modi. Il più semplice COUNT(*) l’abbiamo già visto: effettua il conteggio di tutte le righe presenti nel gruppo, indipendentemente dai valori assunti. Può essere usato anche senza GROUP BY, per calcolare le righe totali presenti in una tabella:

SELECT COUNT(*) FROM Person

Se tra le parentesi specifichiamo un’espressione, verranno contate solo le righe che hanno quell’espressione non nulla. Ad esempio la seguente query raggruppa i libri per anno di pubblicazione, contando quanti sono e quanti sono stati suddivisi per volume.

SELECT pub_year, COUNT(*), COUNT(volume)
FROM Book
GROUP BY pub_year

Se prima dell’espressione indichiamo la parola chiave DISTINCT verranno conteggiate solo le espressioni non nulle e distinte. In questo caso, in cui abbiamo due tabelle in join, avremo come risultato il numero di redattori per ogni libro. Avremo vedremo uno 0 nel caso in cui il libro non ha specificato nessun redattore nel database.

SELECT Book.title, COUNT(DISTINCT personID)
FROM Book
LEFT JOIN Editor ON book.ID = Editor.publicationID
GROUP BY Book.id, Book.title

La funzione SUM

Questa funzione somma i valori dei campi trovati nel gruppo. I valori nulli vengono ignorati, contrariamente a quanto farebbe una somma semplice.

SELECT Person.surname, SUM(Book.pages)
FROM Book
JOIN Editor ON book.ID = Editor.publicationID
JOIN Person ON Editor.personID = Person.ID
GROUP BY Person.ID, Person.surname

Questa interrogazione restituisce il numero di pagine totale editate da ogni redattore.

Le funzioni MIN, MAX e AVG

Con queste funzioni si possono ottenere i valori massimo e minimo di una colonna, in base al criterio di ordinamento predefinito (ad esempio per il testo verrà usato un ordinamento alfabetico). I valori nulli vengono ignorati.

Naturalmente più funzioni possono essere usate nella stessa query. La seguente restituisce, per ogni anno di pubblicazione, il primo titolo in ordine alfabetico, il numero di libri pubblicati, la media del numero di pagine e il numero di pagine del libro più grande:

SELECT Book.pub_year, MIN(title), COUNT(*), AVG(pages), MAX(pages)
FROM Book
GROUP BY pub_year

Filtraggio sul raggruppamento

A differenza di WHERE, che agisce a livello di singola riga, la parola chiave HAVING permette di effettuare un filtraggio sul ragguppamento. Questa clausola si inserisce subito dopo la GROUP BY.

Il criterio di filtraggio può contenere qualsiasi funzione di raggruppamento. Supponiamo di volere vedere in quali abbiamo pubblicato almeno 100 libri:

SELECT Book.pub_year, COUNT(*), AVG(pages)
FROM Book
GROUP BY pub_year HAVING COUNT(*) > 100

Analisi dei dati con ROLLUP e CUBE

Le direttive ROLLUP e CUBE, restituiscono nel risultato ulteriori righe per rappresentare aggregazioni trasversali, ad esempio per calcolare subtotali. Vediamo un esempio concreto:

SELECT Book.pub_year, publisher, COUNT(*), SUM(pages)
FROM Book
GROUP BY pub_year, publisher WITH ROLLUP

Se eseguissimo questa query senza WITH ROLLUP otterremmo, per ogni anno e per ogni casa editrice, il numero di libri pubblicati e il totale delle pagine. Ma se volessimo vedere anche l’aggregazione per anno indipendentemente dall’editore dovremmo effettuare un’altra query. Utilizzando invece il rollup, possiamo vedere anche tali raggruppamenti trasversali, come vediamo dalle ultime tre righe restituite dalla query:

pub_year publisher count pages
1993 1 1 12
1993 NULL 1 12
NULL NULL 6 2509

Come si vede, sono stati fatti anche i raggruppamenti per anno, indipendentemente dall’editore e i totali generali (ultima riga). Non sono stati fatti invece i raggruppamenti per editore indipendentemente dall’anno. Per avere tutte le possibili combinazioni di raggruppamenti si utilizza la direttiva WITH CUBE, per ottenere anche righe fatte così:

pub_year publisher count pages
NULL 5 2 999
NULL NULL 6 2509

Ti consigliamo anche