Учебник PostgreSQL 7.3.3


Агрегатные функции


PostgreSQL, как и многие другие реляционные СУБД, поддерживает агрегатные функции. Агрегатная функция производит вычисление над единичным результатом от множества записей. Например, есть агрегаты для вычисления count (количества), sum (суммы), avg (среднего арифметического), max (максимального значения) и min (минимального значения) списка записей.

В качестве примера, мы можем найти наиболее высокую низкую температуру, создав запрос:

SELECT max(temp_lo) FROM weather;

max ----- 46 (1 row)

Если мы хотим знать, в каком городе (или городах) это происходило, мы можем попытаться создать такой запрос:

SELECT city FROM weather WHERE temp_lo = max(temp_lo); НЕПРАВИЛЬНО

но он не будет работать, потому что агрегат max

нельзя использовать в предложении WHERE. (Это ограничение существует, потому что предложение WHERE

определяет записи, которые будут использованы на стадии обработки агрегатами; и таким образом оно должно уже отработать перед тем, как будут запущены агрегатные функции). Однако, эту ситуацию можно разрешить, если использовать позапрос:

SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);

city --------------- San Francisco (1 row)

Теперь всЈ в порядке, потому что подзапрос является независимым вычислением, которое вычисляет свой собственный агрегат отдельно от того, который работает во внешнем запросе.

Агрегаты являются очень полезными в комбинациях с литералами GROUP BY. Например, мы можем получить максимально низкую температуру, отмеченную в каждом городе с помощью запроса:

SELECT city, max(temp_lo) FROM weather GROUP BY city;

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

который предоставит нам по одной записи на город. Каждый результат агрегата подсчитывается исходя из записей таблицы, которые соответствуют определенному городу. Мы можем фильтровать сгруппированные записи, используя литерал HAVING:

SELECT city, max(temp_lo) FROM weather GROUP BY city HAVING max(temp_lo) < 40;




Начало  Назад  Вперед