Como la mayoría de los demás productos de bases de datos relacionales, PostgreSQL cuenta con funciones de agregados (aggregate functions). Una función de agregado calcula un resultado único a partir de varias filas. Por ejemplo, hay agregados que calculan conteo (count), sumatorias (sum), promedios (avg), máximos (max), mínimos (min) a partir de un conjunto de filas.
Como ejemplo, se puede encontrar la temperatura baja más alta de cualquier ciudad escribiendo:
midb=# SELECT max(temp_lo) FROM weather;
max
-----
46
(1 fila)
Si uno quisiera saber a qué ciudad o ciudades pertenece esa temperatura, uno pensaría en algo como lo siguiente (que es incorrecto):
SELECT city FROM weather WHERE temp_lo = max(temp_lo);
La línea de arriba no funciona porque el agregado max no se puede usar en la cláusula WHERE. (Esta restricción existe porque la cláusula WHERE determina qué filas se van a incluir en el cálculo del agregado; por lo cual debe evaluarse antes de computar cualquier función de agregado). Sin embargo, la consulta puede reestructurarse para lograr el resultado deseado, en este caso usando una subconsulta:
midb=# SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
city
---------------
San Francisco
(1 fila)
Esto funciona bien porque la subconsulta es un cálculo independiente que calcula su agregado de manera separada de lo que sucede en la consulta externa.
Los agregados también son muy útiles en combinación con las cláusulas GROUP BY. Por ejemplo, se puede obtener la temperatura baja mayor observada en cada ciudad con:
midb=# SELECT city, max(temp_lo) FROM weather GROUP BY city;
city | max
---------------+-----
Hayward | 37
San Francisco | 46
(2 filas)
Lo anterior da como resultado una fila por ciudad. Cada resultado agregado se calcula sobre las filas de la tabla que concuerdan con esa ciudad. Estas filas agrupadas se pueden filtrar usando HAVING:
midb=# SELECT city, max(temp_lo) FROM weather GROUP BY city HAVING max(temp_lo) < 40;
city | max
---------+-----
Hayward | 37
(1 fila)