SELECT day, revenue,
SUM(revenue) OVER (ORDER BY day
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
FROM daily_sales;
Результат:
day | revenue | running_total 2026-06-01 | 100 | 100 2026-06-02 | 200 | 300
SELECT user_id, amount,
ROUND(100.0 * amount / SUM(amount) OVER (PARTITION BY user_id), 1) AS pct_of_user
FROM orders;
Результат:
user_id | amount | pct_of_user 1 | 300 | 75.0 1 | 100 | 25.0Порешать SQL-задачи в тренажёре →
SUM() OVER — база задач на running total, долю от целого и «сумму по группе рядом с деталями». На собеседовании часто просят «долю каждого товара в выручке категории» или «накопительную сумму» — и то, и другое это SUM() OVER, а не подзапрос.
GROUP BY схлопывает строки в одну на группу. SUM() OVER считает ту же сумму, но сохраняет все строки — каждая получает значение окна рядом. Поэтому можно вывести и деталь, и агрегат в одной выборке.
SUM(x) OVER (ORDER BY dt ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW). ORDER BY задаёт порядок накопления, рамка ROWS — что суммируется до текущей строки включительно.
При наличии ORDER BY без явной рамки берётся RANGE до текущей строки, и на одинаковых значениях ключа сумма перепрыгнет через все дубли. Явная рамка ROWS делает поведение предсказуемым.
ROW_NUMBER · RANK · DENSE_RANK · LAG · LEAD · NTILE
Открыть SQL-тренажёр (565 задач) →