Uso de funciones de conjunto

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 .