Documentazione di PostgreSQL 9.0 > Tutorial > Il linguaggio SQL > Funzioni aggregate
PrecedenteJoin tra tabelleAggiornamentiSuccessivo

2.7. Funzioni aggregate

Come molti altri database relazionali, PostgreSQL™ supporta funzioni aggregate. Una funzione aggregata calcola un singolo risultato da molteplici righe di input. Per esempio, ci sono aggregate per calcolare il count (conteggio), sum (somma), avg (media), max (massimo) and min (minimo) di un insieme di righe.

Come esempio, è possibile trovare la temperatura-minima più alta letta ovunque con:

SELECT max(temp_lo) FROM weather;

 max
-----
  46
(1 row)

Se si volesse conoscere a quale città (o più città) appartiene l'occorrrenza trovata, si potrebbe provare con:

SELECT city FROM weather WHERE temp_lo = max(temp_lo);     WRONG

ma questo non funzionerà dato che l'aggregata max non può essere usata nella clausola WHERE. (Questa restrizione esiste dato che la clausola WHERE determina quali righe saranno incluse nel calcolo dell'aggregata; così, ovviamente, deve essere analizzata prima che la funzione aggregata sia calcolata). Comunque, dato che è frequente il caso in cui la query è ripetuta per ottenere il risultato desiderato, si usa una sottoquery:

SELECT city FROM weather
    WHERE temp_lo = (SELECT max(temp_lo) FROM weather);

     city
---------------
 San Francisco
(1 row)

Questa funzionerà dato che la sottoquery è un calcolo indipendente che esegue la propria funzione aggregata separatamente da quello che succede nella query esterna.

Le aggregate sono anche utili in combinazione con le clausole GROUP BY. Per esempio, è possibile ottenere la temperatura-minima massima registrata in ogni città con:

SELECT city, max(temp_lo)
    FROM weather
    GROUP BY city;

     city      | max
---------------+-----
 Hayward       |  37
 San Francisco |  46
(2 rows)

che restituisce una riga in output per città. Ogni risultato dell'aggregata è calcolato sulle righe della tabella che corrispondono a quella città. È possibile filtrare queste righe raggrupate usando HAVING:

SELECT city, max(temp_lo)
    FROM weather
    GROUP BY city
    HAVING max(temp_lo) < 40;

  city   | max
---------+-----
 Hayward |  37
(1 row)

che restituisce gli stessi risultati solamente per città che hanno tutti i valori di temp_lo sotto 40. Infine, se ci interessano solo le città il cui nome comincia con «S», potremmo fare:

SELECT city, max(temp_lo)
    FROM weather
    WHERE city LIKE 'S%'1
    GROUP BY city
    HAVING max(temp_lo) < 40;

1

L'operatore LIKE confronta secondo un modello ed è spiegato in Sezione 9.7, «Confronto con modelli».

È importante capire l'interazione tra le aggregate e le clausole di SQL WHERE e HAVING. La fifferenza fondamentale tra WHERE e HAVING è questa: WHERE seleziona righe di input prima che le aggregate e i raggrumenti vengano svolti (così, controlla quali righe finiscono nel calcolo dell'aggregata), mentre HAVING seleziona gruppi di righe dopo che i gruppi e le aggregate sono calcolate. Così, la clausola WHERE non deve contenere funzioni aggregate; non ha senso provare ad usare un'aggregata per determinare quali righe saranno input delle aggregate. D'altro canto, la clausola HAVING contiene sempre funzioni aggregate. (In senso stretto, è permesso scrivere una clausola HAVING che non usa le aggregate, ma raramente è utile. La stessa condizione può essere usata più efficentemente nella WHERE).

Nell'esempio precedente, è possibile applicare la restrizione del nome della città nella WHERE, dato che non necessita di aggregate. Questo è più efficiente che aggiungere la restrizione alla HAVING, perchè si eviterà di fare il raggrupamento e i calcoli aggrgeati per tutte le righe che falliscono il controllo WHERE.

Documentazione di PostgreSQL 9.0 > Tutorial > Il linguaggio SQL > Funzioni aggregate
PrecedenteJoin tra tabelleAggiornamentiSuccessivo