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 no funcionará debido a que la función max() no puede ser usada en
where. Sin embargo, podemos replantar la consulta
para llevar a cabo lo que buscamos. En este caso usando una
subseleccion:
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
|
Lo que ya es correcto, ya que la subselección es una operación independiente
que calcula su propia función de grupo sin importar lo que pase 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
filtro de
where .