Oltre a leggere i valori “riga per riga”, in molti casi è utile sottoporre le tabelle a valutazioni che li coinvolgono in gruppo. A questo scopo si utilizzano le cosiddette funzioni di aggregazione, tre la quali troviamo:
-
COUNT
: restituisce il numero di elementi; -
COUNT(DISTINCT)
: variante diCOUNT
che considera i valori duplicati solo una volta; -
MAX
: restituisce il valore massimo dell'insieme; -
MIN
: restituisce il valore minimo dell'insieme; -
AVG
: restituisce il valore medio dell'insieme; -
SUM
: somma i valori.
Esistono altre funzioni di questo genere. Se ne può trovare un elenco esaustivo nell'apposita pagina della documentazione ufficiale. Esiste anche un nutrito gruppo di funzioni a carattere statistico.
Funzioni di aggregazione: esempi
Prendiamo ad esempio una tabella che, nel client mysql, si mostra come in figura:
Il campo importo rappresenta simbolicamente un costo sostenuto mentre descrizione ne rappresenta la causale.
Gli esempi qui di seguito riportati utilizzano le funzioni di aggregazione sul predetto insieme, e mostrano i risultati ottenuti:
> SELECT COUNT(importo) FROM spese;
9
> SELECT COUNT(DISTINCT importo) FROM spese;
7
> SELECT SUM(importo) FROM spese;
527
> SELECT AVG(importo) FROM spese;
58.5556
> SELECT MIN(importo) FROM spese;
4
> SELECT MAX(importo) FROM spese;
150
Si noti che i valori 4 e 65 sono ripetuti nell'insieme: questo giustifica la differenza di risultato tra COUNT
e COUNT(DISTINCT)
.
È importante notare il rapporto che le funzioni di aggregazione hanno con operatori molto importanti di SQL, quali WHERE
e GROUP BY
. Il primo influenza la quantità di elementi che verranno sottoposti alla funzione di interazione. In una query come la seguente verrà prima eseguito il filtro sulle righe e, solo successivamente, sarà applicata la funzione di aggregazione sui record risultanti:
> SELECT SUM(importo) FROM spese WHERE descrizione='cartoleria';
36
Per quanto riguarda l'uso del costrutto GROUP BY
con funzioni di aggregazione, partiamo da un esempio che mostra un risultato ingannevole. Supponiamo di svolgere la seguente query:
> SELECT descrizione, MIN(importo) FROM spese;
alimentari | 4
Il valore minimo individuato è 4 (e ciò è corretto) ma l'associazione sulla stessa riga del termine alimentari potrebbe - ingannevolmente – indurre a pensare che questa sia la descrizione associata al valore. Controllando la figura precedente si vede, invece, che la descrizione del valore 4 è cartoleria. Cos'è successo quindi? La query ha prodotto il valore minimo corrispondente all'invocazione di MIN
, e non sapendo quale elemento del campo descrizione associare ha prelevato il primo valore che ha trovato.
Per avere dei risultati corretti e che non traggano in inganno come nell'esempio precedente è necessario che la proiezione, ossia l'elenco dei campi indicati dopo il SELECT
, contenga funzioni di aggregazione ed eventuali campi semplici solo se elencati in una clausola GROUP BY
.
La seguente query:
> SELECT descrizione, MIN(importo) FROM spese GROUP BY descrizione;
alimentari | 23
cartoleria | 4
strumenti | 88
mostra un risultato veritiero. Saranno raggruppati i record in base alla descrizione e per ogni gruppo verrà individuato il minimo.
La clausola UNION
La clausola UNION
viene usata per unire i risultati di due query.
Affinchè il tutto possa funzionare è necessario che le proiezioni delle due SELECT
coinvolte siano composte dallo stesso numero di campi, e che i tipi di dato degli stessi siano compatibili con quelli corrispondenti nell'altra query.
Ad esempio, immaginiamo di avere due tabelle con la stessa struttura, di nome dati e dati_archivio, dove quest'ultima, come spesso può capitare, contiene vecchi record un tempo inseriti nella prima ed ormai conservati solo per valore storico:
SELECT descrizione, importo, data_operazione FROM dati
UNION
SELECT descrizione, importo, data_operazione FROM dati_archiviati
Il risultato sarà un unico set di record reperiti da entrambe le tabelle.
Al posto di UNION
si può usare UNION ALL
, che mostrerà anche i valori duplicati, mentre il comportamento di default di UNION
non lo fa.