В оконных функциях важны не только
PARTITION BY и ORDER BY, но и то, какие строки попадают в окно вычисления. За это отвечают оконные фреймы — ROWS и RANGE.Таблица операций:
transactions(id, user_id, amount, created_at)
Накопительная сумма по пользователю:
SUM(amount) OVER (
PARTITION BY user_id
ORDER BY created_at
)
При наличии
ORDER BY и отсутствии явного фрейма в большинстве СУБД используется RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.Если значения
created_at совпадают, сумма считается сразу по группе строк (peers).Среднее по последним 3 операциям:
AVG(amount) OVER (
PARTITION BY user_id
ORDER BY created_at, id
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
)
ROWS формирует окно по количеству строк. Детерминированный ORDER BY необходим для воспроизводимого результата.Сумма за последние 7 дней (пример для PostgreSQL):
SUM(amount) OVER (
PARTITION BY user_id
ORDER BY created_at
RANGE BETWEEN INTERVAL '7 days' PRECEDING AND CURRENT ROW
)
RANGE формирует окно по значениям ORDER BY. Поддержка и синтаксис интервалов зависят от СУБД; часто допускается только одно выражение в ORDER BY.🔥 Важно помнить:
ROWS — предсказуем по количеству строк, RANGE — удобен для временных интервалов и peer-групп, неявный фрейм может менять результат вычислений➡️ SQL Ready | #практика