2.7. Fonctions d'agr�gat

Comme la plupart des autres produits de bases de donn�es relationnelles, PostgreSQL supporte les fonctions d'agr�gat. Une fonction d'agr�gat calcule un seul r�sultat � partir de plusieurs lignes en entr�e. Par exemple, il y a des agr�gats pour calculer le compte (count), la somme (sum), la moyenne (avg), le maximum (max) et le minimum (min) d'un ensemble de lignes.

Comme exemple, nous pouvons trouvez la temp�rature la plus haute parmi les temp�ratures les plus faibles avec :

SELECT max(temp_basse) FROM temps;

 max
-----
  46
(1 row)

Si nous voulons conna�tre dans quelle ville (ou villes) ces lectures se sont produites, nous pouvons essayer

SELECT ville FROM temps WHERE temp_basse = max(temp_basse);    
FAUX

mais cela ne marchera pas puisque l'agr�gat max ne peut pas �tre utilis� dans une clause WHERE. (Cette restriction existe parce que la clause WHERE d�termine les lignes qui seront trait�es par l'agr�gat ; donc les lignes doivent �tre �valu�es avant que les fonctions d'agr�gat calculent.) Cependant, comme cela est souvent le cas, la requ�te peut �tre r�p�t�e pour arriver au r�sultat attendu, ici en utilisant une sous-requ�te :

SELECT ville FROM temps
    WHERE temp_basse = (SELECT max(temp_basse) FROM temps);

     ville
---------------
 San Francisco
(1 row)

Ceci est bon car la sous-requ�te est un calcul ind�pendant qui traite son propre agr�gat s�par�ment � partir de ce qui se passe dans la requ�te externe.

Les agr�gats sont �galement tr�s utiles s'ils sont combin�s avec les clauses GROUP BY. Par exemple, nous pouvons obtenir la plus haute temp�rature parmi les temp�ratures les plus faibles observ�es dans chaque ville avec

SELECT ville, max(temp_basse)
    FROM temps
    GROUP BY ville;

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

ce qui nous donne une ligne par ville dans le r�sultat. Chaque r�sultat d'agr�gat est calcul� avec les lignes de la tables correspondant � la ville. Nous pouvons filtrer ces lignes group�es en utilisant HAVING :

SELECT ville, max(temp_basse)
    FROM temps
    GROUP BY ville
    HAVING max(temp_basse) < 40;

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

ce qui nous donnes le m�me r�sultat uniquement pour les villes qui ont toutes leurs valeurs de temp_basse en-dessous de 40. Pour finir, si nous nous pr�occupons seulement des villes dont le nom commence par <<�S�>>, nous pouvons faire

SELECT ville, max(temp_basse)
    FROM temps
    WHERE ville LIKE 'S%'(1)
    GROUP BY ville
    HAVING max(temp_basse) < 40;

(1)
L'op�rateur LIKE fait la correspondance avec un mod�le ; cela est expliqu� dans la Section 9.7.

Il est important de comprendre l'interaction entre les agr�gats et les clauses SQL WHERE et HAVING. La diff�rence fondamentale entre WHERE et HAVING est que WHERE s�lectionne les lignes en entr�e avant que les groupes et les agr�gats ne soient trait�s (donc, cette clause contr�le quelles lignes vont dans le calcul de l'agr�gat) tandis que HAVING s�lectionne les lignes group�es apr�s que les groupes et les agr�gats aient �t� trait�s. Donc, la clause WHERE ne doit pas contenir des fonctions d'agr�gat ; cela n'a aucun sens d'essayer d'utiliser un agr�gat pour d�terminer quelles lignes seront en entr�e des agr�gats. D'un autre c�t�, la clause HAVING contient toujours des fonctions d'agr�gat. (Pour �tre pr�cis, vous �tes autoris�s � �crire une clause HAVING qui n'utilise pas d'agr�gats, mais c'est inutile. La m�me condition pourra �tre utilis�e plus efficacement par un WHERE.)

Dans l'exemple pr�c�dent, nous pouvons appliquer la restriction sur le nom de la ville dans WHERE puisque cela n'a besoin d'aucun agr�gat. C'est plus efficace que d'ajouter la restriction dans HAVING parce que nous �vitons le groupement et les calculs d'agr�gat pour toutes les lignes qui ont �chou� lors du contr�le fait par WHERE.