Агрегатные функции
Агрегатные функции вычисляют результат на основе набора входных значений и обычно используются в SELECT-запросах для агрегирования данных по набору строк. Типичные примеры — вычисление суммы, количества или среднего значения.
Типовые агрегатные функции — это SUM()
, COUNT()
, AVG()
, MIN()
и MAX()
.
В сочетании с GROUP BY
эти функции вычисляют агрегированные значения для каждой группы.
Выражение HAVING
позволяет фильтровать группы после агрегации, аналогично тому, как WHERE
фильтрует отдельные строки до группировки.
Обзор
Обзор синтаксиса
Большинство агрегатных функций принимает один аргумент — столбец или выражение, которое подлежит агрегации:
<aggregate_name>(expression)
где:
-
aggregate_name
— имя функции (например,SUM
,AVG
,COUNT
), которая выполняет агрегацию. -
expression
— столбец или выражение, значения которых агрегируются.
Например, SUM(quantity)
вычисляет общую сумму значений в столбце quantity
.
Функция COUNT(product)
подсчитывает количество значений, не равных NULL
, в столбце product
.
Некоторые агрегатные функции принимают несколько аргументов:
<aggregate_name>(expression [, ...] )
Например, функция string_agg(<expression>, <delimiter>)
объединяет строки, используя указанный разделитель.
Вы можете выполнять агрегацию по всем значениям или только по уникальным, а также фильтровать строки перед агрегацией с помощью следующего синтаксиса:
<aggregate_name>( [ ALL | DISTINCT ] expression [, ...] ) [ FILTER ( WHERE <condition> ) ]
где:
-
ALL
— (опционально, по умолчанию) агрегирует все входные значения. -
DISTINCT
— (опционально) агрегирует только уникальные входные значения, игнорируя дубликаты. -
FILTER (WHERE <condition>)
— (опционально) фильтрует строки, участвующие в агрегации. Если указанFILTER
, в вычисление агрегата попадут только строки, удовлетворяющие<condition>
.
Агрегатные выражения
Агрегатное выражение применяет агрегатную функцию к набору строк, полученных в результате SQL-запроса. Агрегатная функция выполняет вычисление по набору значений и возвращает один результат, например сумму, количество или среднее значение.
Синтаксис агрегатного выражения имеет одну из следующих форм:
-
<aggregate_name>(expression [, …]) [ FILTER (WHERE <condition>) ]
— агрегирует все значения, не равныеNULL
. -
<aggregate_name>(ALL expression [, …]) [ FILTER (WHERE <condition>) ]
— аналогичен предыдущей форме;ALL
используется по умолчанию и агрегирует все значения, не равныеNULL
. -
<aggregate_name>(DISTINCT expression [, …]) [ FILTER (WHERE <condition>) ]
— агрегирует только уникальные значения, не равныеNULL
. -
<aggregate_name>(*) [ FILTER (WHERE <condition>) ]
— агрегирует все строки, включая строки со значениямиNULL
. Обычно используется сCOUNT(*)
для подсчета строк. -
<aggregate_name>( [ expression [, … ] ] ) WITHIN GROUP ( <order_by_clause> ) [ FILTER ( WHERE <condition> ) ]
— форма агрегирования с учетом порядка, в которой значения сортируются перед агрегированием.
Ограничения агрегатных выражений
-
Агрегатное выражение можно использовать только в списке результатов или в выражении
HAVING
командыSELECT
. Использование в других частях запроса, таких какWHERE
, запрещено, так как они вычисляются до расчета агрегатных функций. Это ограничение действует на уровне запроса, которому принадлежит агрегат. -
Когда агрегатное выражение используется в подзапросе, оно обычно применяется к строкам, возвращаемым этим подзапросом. Однако если аргументы агрегатной функции ссылаются только на столбцы внешнего запроса, агрегат вычисляется на уровне этого внешнего запроса. В таком случае подзапрос рассматривает результат агрегата как постоянное значение.
-
Нельзя использовать агрегатную функцию в качестве аргумента другой агрегатной функции.
-
Нельзя передавать оконные функции в качестве аргумента в агрегатные функции.
Встроенные агрегатные функции
Greengage DB позволяет использовать агрегатные функции, поддерживаемые PostgreSQL, например:
-
SUM()
— возвращает сумму значений. -
AVG()
— возвращает среднее значение. -
COUNT()
— возвращает количество значений. -
MAX()
— возвращает максимальное значение. -
MIN()
— возвращает минимальное значение.
Чтобы увидеть полный список агрегатных функций, смотрите соответствующую статью в документации PostgreSQL: Aggregate Functions.
Помимо агрегатных функций, специфичных для PostgreSQL, Greengage DB предоставляет дополнительный набор аналитических функций, перечисленных в таблице ниже.
Функция | Тип возвращаемого значения | Описание |
---|---|---|
MEDIAN(expr) |
|
Вычисляет медианное значение. Поддерживает двумерные массивы и обрабатывает их как матрицы |
SUM(array[]) |
|
Выполняет покомпонентное суммирование значений, являющихся двумерными числовыми массивами (матричное суммирование) |
PIVOT_SUM(label[], label, expr) |
|
Выполняет сводную агрегацию, суммируя значения по группам меток. Значения повторяющихся меток складываются |
UNNEST(array[]) |
набор из |
Разворачивает массив в набор строк, возвращая каждый элемент отдельно |
Вы можете создавать пользовательские агрегатные функции с помощью команды CREATE AGGREGATE
.
Примеры использования
Базовые агрегатные запросы
Этот SQL-запрос использует агрегатную функцию SUM()
для вычисления общего количества всех продаж:
SELECT SUM(quantity) AS total_quantity
FROM sales;
Результат выглядит следующим образом:
total_quantity ---------------- 31 (1 row)
Следующий SQL-запрос использует функцию SUM()
для расчета общей суммы продаж, складывая результаты выражения price * quantity
для всех строк в таблице:
SELECT SUM(price * quantity) AS total_sales
FROM sales;
Вывод выглядит следующим образом:
total_sales ------------- 8670.00 (1 row)
Этот запрос вычисляет количество проданных товаров в каждой категории с использованием GROUP BY
:
SELECT category,
SUM(quantity) AS total_quantity
FROM sales
GROUP BY category;
Результат выглядит следующим образом:
category | total_quantity -------------+---------------- Home | 8 Clothing | 10 Electronics | 13 (3 rows)
Следующий запрос фильтрует агрегированные результаты с помощью HAVING
и возвращает категории, в которых общее количество проданных товаров больше или равно 10
:
SELECT category,
SUM(quantity) AS total_quantity
FROM sales
GROUP BY category
HAVING SUM(quantity) >= 10;
Результат должен быть следующим:
category | total_quantity -------------+---------------- Electronics | 13 Clothing | 10 (2 rows)
Агрегатные выражения
Этот SQL-запрос подсчитывает все строки в таблице sales
, включая строки со значениями NULL
в любом столбце:
SELECT COUNT(*) AS total_row_count
FROM sales;
Результат выглядит следующим образом:
total_row_count ----------------- 20 (1 row)
Следующий SQL-запрос подсчитывает количество строк, в которых столбец region
не равен NULL
, включая все неуникальные значения:
SELECT COUNT(region) AS non_null_region_count
FROM sales;
Результат следующий:
non_null_region_count ----------------------- 18 (1 row)
Этот запрос выполняет ту же операцию, что и предыдущий, но явно использует ключевое слово ALL
:
SELECT COUNT(ALL region) AS non_null_region_count
FROM sales;
Этот SQL-запрос подсчитывает количество уникальных значений, не равных NULL
, в столбце region
, показывая, сколько различных регионов представлено в данных о продажах:
SELECT COUNT(DISTINCT region) AS distinct_region_count
FROM sales;
Вывод должен выглядеть следующим образом:
distinct_region_count ----------------------- 4 (1 row)
Этот запрос подсчитывает количество строк, в которых значение столбца region
равно 'North'
, используя FILTER
для учета только таких строк:
SELECT COUNT(*) FILTER (WHERE region = 'North') AS north_region_count
FROM sales;
Результат выглядит так:
north_region_count -------------------- 6 (1 row)
Основные агрегатные функции
Этот SQL-запрос вычисляет общее количество проданных товаров для каждой категории с помощью функции SUM()
:
SELECT category,
SUM(quantity) AS total_quantity
FROM sales
GROUP BY category;
category | total_quantity -------------+---------------- Home | 8 Electronics | 13 Clothing | 10 (3 rows)
Следующий запрос вычисляет среднюю цену товаров в каждой категории с помощью функции AVG()
:
SELECT category,
AVG(price) AS avg_price
FROM sales
GROUP BY category;
category | avg_price -------------+---------------------- Electronics | 683.3333333333333333 Clothing | 39.0000000000000000 Home | 111.6666666666666667 (3 rows)
ROUND()
, чтобы округлять числовые значения до заданного количества знаков после запятой.Этот SQL-запрос подсчитывает количество записей о продажах для каждой категории с помощью функции COUNT()
:
SELECT category,
COUNT(*) AS sales_count
FROM sales
GROUP BY category;
category | sales_count -------------+------------- Home | 6 Clothing | 5 Electronics | 9 (3 rows)
Следующий запрос использует функцию MAX()
, чтобы найти наивысшую цену для каждой категории товаров:
SELECT category,
MAX(price) AS max_price
FROM sales
GROUP BY category;
category | max_price -------------+----------- Clothing | 60.00 Electronics | 1200.00 Home | 200.00 (3 rows)
Данный SQL-запрос возвращает минимальную цену в каждой категории товаров с помощью функции MIN()
:
SELECT category,
MIN(price) AS min_price
FROM sales
GROUP BY category;
category | min_price -------------+----------- Electronics | 150.00 Home | 45.00 Clothing | 25.00 (3 rows)
Расширенные аналитические функции
Следующий SQL-запрос вычисляет медианную цену для каждой категории товаров:
SELECT category,
MEDIAN(price) AS median_price
FROM sales
GROUP BY category;
category | median_price -------------+-------------- Home | 85 Clothing | 25 Electronics | 800 (3 rows)
Следующий запрос находит медианную дату продажи для каждой категории:
SELECT category,
MEDIAN(sale_date) AS median_sale_date
FROM sales
GROUP BY category;
category | median_sale_date -------------+------------------------ Clothing | 2025-02-13 00:00:00+00 Electronics | 2025-02-07 00:00:00+00 Home | 2025-02-19 12:00:00+00 (3 rows)
Этот SQL-запрос подсчитывает общее количество проданных товаров.
Данные разбиваются по регионам с помощью функции PIVOT_SUM()
, которая суммирует значения, сгруппированные по заданным меткам регионов:
SELECT product_name,
PIVOT_SUM(ARRAY ['North', 'South', 'East', 'West'], region, quantity) AS quantity_per_region
FROM sales
WHERE region IS NOT NULL
GROUP BY product_name;
product_name | quantity_per_region --------------+--------------------- Smartphone | {0,0,0,3} Laptop | {3,0,0,0} Headphones | {6,0,0,0} T-Shirt | {0,0,7,0} Desk Chair | {0,3,0,0} Blender | {0,1,0,0} Jacket | {0,0,3,0} Coffee Maker | {0,2,0,0} (8 rows)
Расширенные аналитические функции: двумерные массивы
Чтобы выполнить примеры из этого раздела, создайте таблицу metrics_data
:
CREATE TABLE metrics_data
(
id SERIAL,
values FLOAT8[][]
)
WITH (appendoptimized = true)
DISTRIBUTED BY (id);
Добавьте данные:
INSERT INTO metrics_data (values)
VALUES (ARRAY [[1.5, 2.0], [3.1, 4.0]]),
(ARRAY [[0.5, 1.0], [1.9, 2.0]]);
Этот запрос поэлементно суммирует двумерные массивы из столбца values
во всех строках таблицы metrics_data
:
SELECT SUM(values) AS total_array_sum
FROM metrics_data;
total_array_sum ----------------- {{2,3},{5,6}} (1 row)
Этот запрос показывает, как использовать функцию UNNEST()
, чтобы развернуть столбец с двумерным массивом в отдельные скалярные значения:
SELECT UNNEST(values) AS value
FROM metrics_data;
value ------- 1.5 2 3.1 4 0.5 1 1.9 2 (8 rows)