Como otros lenguajes de consulta, PostgreSQL soporta funciones de conjunto. Una función de conjunto calcula un único resultado a partir de múltiples filas de entrada. Por ejemplo, existen funciones globales para calcular count(contar) ,sum (sumar), avg (media), max (máximo) and min (mínimo) sobre un conjunto de instancias.
Es importante comprender la relación entre las funciones de conjunto y las cláusulas SQL where y having . . La diferencia fundamental entre where y having es que: where selecciona las columnas de entrada antes de los grupos y entonces se computan las funciones de conjunto (de este modo controla qué filas van a la función de conjunto), mientras que having selecciona grupos de filas después de los grupos y entonces se computan las funciones de conjunto. De este modo la cláusula where puede no contener funciones de conjunto puesto que no tiene sentido intentar usar una función de conjunto para determinar qué fila será la entrada de la función. Por otra parte, las cláusulas having siempre contienen funciones de conjunto. (Estrictamente hablando, usted puede escribir una cláusula havingque no use funciones de grupo, pero no merece la pena. La misma condición podría ser usada de un modo más eficaz conwhere .)
Como ejemplo podemos buscar la mínima temperatura en cualquier parte con
SELECT max(temp_lo) FROM weather;
Si queremos saber qué ciudad o ciudades donde se dieron estas temperaturas, podemos
probar
SELECT city FROM weather WHERE temp_lo = max(temp_lo);
pero esto no funcionará debido a que la función max() no puede ser usada en
where. Sin embargo y como es frecuente, la consulta
puede ser replanteada para llevar a cabo lo que se buscaba. En este caso
usando una
subseleccion:
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
Esto es correcto, ya que la subselección es una operación independiente
que calcula su propia función de grupo separadamente de lo que ocurre en
el select exterior.
Las funciones de grupo son también muy útiles combinándolas con cláusulas group by . Por ejemplo, podemos obtener la temperatura mínima tomada en cada ciudad con :
SELECT city, max(temp_lo)
FROM weather
GROUP BY city;
que nos devuelve una fila por ciudad. Podemos filtrar estas filas agrupadas
usando having:
SELECT city, max(temp_lo)
FROM weather
GROUP BY city
HAVING min(temp_lo) < 0;
que nos da los mismos resultados, pero de ciudades con temperaturas bajo cero.
Finalmente, si sólo nos interesan las ciudades cuyos nombres empiecen por 'P',
deberíamos hacer :
SELECT city, max(temp_lo)
FROM weather
WHERE city like 'P%'
GROUP BY city
HAVING min(temp_lo) < 0;
Tenga en cuenta que podemos aplicar la restricción del nombre de ciudad en
where, ya que no necesita funciones de conjunto. Esto es
más eficaz que añadir la restricción a having,debido a que
evitamos hacer los cálculos de grupo para todas las filas que no pasan el
chequeo de where .