Агрегатные оконные функции: SUM, AVG, COUNT
Pareto coreАгрегатные функции, знакомые по работе с GROUP BY, можно использовать и как оконные — это открывает мощные возможности для расчета накопительных итогов, скользящих средних и сравнения каждой строки с агрегатом группы, сохраняя при этом детализацию исходных данных.
Агрегатные функции в оконном контексте
Когда SUM(), AVG(), COUNT(), MIN() или MAX() используются с конструкцией OVER(), они вычисляют агрегат не для всей группы сразу, а для каждой строки с учетом определенного "окна" строк. Это позволяет добавить к детальным данным сводные показатели без потери информации.
Базовый пример: Добавим к каждому заказу общую сумму всех заказов клиента:
SELECT
customer_id,
order_id,
amount,
SUM(amount) OVER (PARTITION BY customer_id) AS customer_total
FROM orders;
| customer_id | order_id | amount | customer_total |
|---|---|---|---|
| 101 | 5001 | 1500 | 5600 |
| 101 | 5012 | 2300 | 5600 |
| 101 | 5023 | 1800 | 5600 |
| 102 | 5002 | 900 | 2100 |
| 102 | 5018 | 1200 | 2100 |
Каждая строка сохранена, но теперь можно сразу увидеть, какую долю составляет конкретный заказ от общей суммы клиента: amount / customer_total.
Накопительные суммы (Running Total)
Накопительная сумма — это итог, который увеличивается от строки к строке. Для её расчета используется ORDER BY внутри окна: функция суммирует все строки от начала партиции до текущей строки включительно.
Пример: Рассчитаем накопительную выручку по дням:
SELECT
sale_date,
daily_revenue,
SUM(daily_revenue) OVER (ORDER BY sale_date) AS cumulative_revenue
FROM daily_sales
ORDER BY sale_date;
| sale_date | daily_revenue | cumulative_revenue |
|---|---|---|
| 2024-01-01 | 10000 | 10000 |
| 2024-01-02 | 15000 | 25000 |
| 2024-01-03 | 12000 | 37000 |
| 2024-01-04 | 18000 | 55000 |
Накопительная сумма позволяет отслеживать прогресс к целевому показателю и строить графики роста метрик.
Накопительная сумма внутри групп:
SELECT
category,
sale_date,
daily_revenue,
SUM(daily_revenue) OVER (
PARTITION BY category
ORDER BY sale_date
) AS category_cumulative
FROM sales
ORDER BY category, sale_date;
Здесь накопительная сумма рассчитывается отдельно для каждой категории товаров, начинаясь заново при смене категории.
Скользящие окна (Moving Windows)
Скользящее окно — это фиксированный диапазон строк относительно текущей, используемый для расчета метрик "в динамике". Конструкция ROWS BETWEEN явно задает границы окна.
Синтаксис:
FUNCTION() OVER (
ORDER BY column
ROWS BETWEEN N PRECEDING AND M FOLLOWING
)
N PRECEDING— N строк перед текущейCURRENT ROW— текущая строкаM FOLLOWING— M строк после текущейUNBOUNDED PRECEDING— все строки от начала до текущей (для накопительных итогов)
Пример: Скользящее среднее за 3 дня (текущий день + 2 предыдущих):
SELECT
sale_date,
daily_revenue,
AVG(daily_revenue) OVER (
ORDER BY sale_date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS moving_avg_3d
FROM daily_sales
ORDER BY sale_date;
| sale_date | daily_revenue | moving_avg_3d |
|---|---|---|
| 2024-01-01 | 10000 | 10000.00 |
| 2024-01-02 | 15000 | 12500.00 |
| 2024-01-03 | 12000 | 12333.33 |
| 2024-01-04 | 18000 | 15000.00 |
| 2024-01-05 | 14000 | 14666.67 |
Для первой строки окно содержит только её саму, для второй — две строки, начиная с третьей — полное окно из трёх строк. Скользящее среднее сглаживает колебания и помогает выявлять тренды.
Скользящая сумма за последние 7 дней:
SELECT
sale_date,
daily_revenue,
SUM(daily_revenue) OVER (
ORDER BY sale_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS sum_last_7_days
FROM daily_sales;
Это полезно для расчета метрик типа "продажи за последнюю неделю" для каждого дня.
Сравнение с агрегатом группы
Частая задача — показать, как каждая строка соотносится со средним или суммой по группе:
SELECT
category,
product_name,
sales,
AVG(sales) OVER (PARTITION BY category) AS category_avg,
sales - AVG(sales) OVER (PARTITION BY category) AS diff_from_avg
FROM products;
Этот запрос добавляет к каждому товару среднее значение продаж по его категории и отклонение от этого среднего, позволяя сразу увидеть лидеров и аутсайдеров.
Ключевые выводы
- Агрегатные оконные функции сохраняют детализацию данных, добавляя к каждой строке сводные показатели.
- Накопительные суммы рассчитываются с помощью
ORDER BYбез явного указания границ окна (по умолчаниюUNBOUNDED PRECEDING AND CURRENT ROW). ROWS BETWEENявно определяет границы скользящего окна для расчета скользящих средних, сумм и других метрик в динамике.- Комбинация
PARTITION BYиORDER BYпозволяет строить сложные аналитические расчеты внутри групп с учетом временной последовательности.
AI-generated · source-grounded review
🛡 Fact-checked: 2 risky claims verified · 0 removed · confidence: high
A second opinion has not checked this lesson.
On your own course these buttons answer instantly, quizzes track what you've mastered, and lessons adapt to your gaps. Sign up free →