Нарастающий итог: OVER с ORDER BY
Содержание курса
Нарастающий итог SUM и AVG внутри каждой категории: полный запрос с PARTITION BY
Соберём всё вместе на таблице с категориями:
CREATE TABLE sales (
sale_id INTEGER PRIMARY KEY,
category TEXT,
sale_date TEXT,
amount INTEGER
);
INSERT INTO sales VALUES
(1, 'Книги', '2024-01-01', 500),
(2, 'Книги', '2024-01-02', 300),
(3, 'Книги', '2024-01-03', 200),
(4, 'Электроника', '2024-01-01', 1200),
(5, 'Электроника', '2024-01-02', 800);
SELECT
sale_id,
category,
sale_date,
amount,
SUM(amount) OVER (
PARTITION BY category
ORDER BY sale_date, sale_id
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total,
AVG(amount) OVER (
PARTITION BY category
ORDER BY sale_date, sale_id
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_avg
FROM sales
ORDER BY category, sale_date, sale_id;
Результат:
| sale_id | category | sale_date | amount | running_total | running_avg |
|---|---|---|---|---|---|
| 1 | Книги | 2024-01-01 | 500 | 500 | 500.0 |
| 2 | Книги | 2024-01-02 | 300 | 800 | 400.0 |
| 3 | Книги | 2024-01-03 | 200 | 1000 | 333.33… |
| 4 | Электроника | 2024-01-01 | 1200 | 1200 | 1200.0 |
| 5 | Электроника | 2024-01-02 | 800 | 2000 | 1000.0 |
PARTITION BY category сбрасывает накопитель на каждой новой категории: строка 4 начинает свой нарастающий итог с нуля, не складываясь с книжными продажами. Внутри каждой категории ORDER BY sale_date, sale_id задаёт однозначный порядок, а ROWS-рамка гарантирует, что каждая следующая строка добавляет ровно своё amount.
AVG работает по той же рамке: в знаменателе — количество строк от начала раздела до текущей. После первой строки среднее равно самому значению, после второй — среднему двух, и так далее. Это удобно, когда нужно видеть, как меняется средний чек по мере накопления данных.
Оба столбца — running_total и running_avg — вычисляются независимо: каждая оконная функция имеет собственное определение OVER и не влияет на другую. Число строк в результате всегда равно числу строк в исходной таблице — оконные функции не схлопывают данные.
