Обновить

Семь строк в SQL — ещё не семь дней. Как пропуски дат меняют скользящую сумму

Для показателя «за последние семь дней» легко написать:

SUM(amount) OVER (  ORDER BY day  ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
)

Но ROWS отсчитывает строки. Если в таблице нет дней без продаж, семь соседних строк могут охватывать несколько недель.

Проверим на учебном примере для SQLite. В таблице одна строка на день с продажами; в остальные дни продаж действительно не было. Суммы для простоты записаны в рублях.

WITH daily(day, amount) AS (  VALUES    ('2026-10-01', 10),    ('2026-10-09', 20),    ('2026-10-10', 30)
)
SELECT  day,  SUM(amount) OVER (    ORDER BY day    ROWS BETWEEN 6 PRECEDING AND CURRENT ROW  ) AS sum_by_rows,  SUM(amount) OVER (    ORDER BY julianday(day)    RANGE BETWEEN 6 PRECEDING AND CURRENT ROW  ) AS sum_by_days
FROM daily
ORDER BY day;

Результат:

Для 10 октября нужный период — с 4 по 10 октября включительно. Продажа 1 октября в него не входит, поэтому сумма равна 50. Окно по строкам захватывает все три имеющиеся записи и возвращает 60.

В варианте с RANGE функция julianday(day) даёт числовую шкалу дней. Граница 6 PRECEDING охватывает текущий день и шесть предыдущих. Здесь используются корректные даты без времени; для временных меток сначала нужно определить часовой пояс отчёта и получить дневные итоги.

Есть и второй способ: дополнить таблицу календарём, чтобы каждому дню соответствовала строка, а подтверждённому отсутствию продаж — ноль. Тогда ROWS снова будет отсчитывать дни. Это также позволит показать на графике даты без продаж.

Для средней за семь календарных дней различие ещё заметнее. Если в том же семидневном окне заменить SUM(amount) на AVG(amount), на 10 октября получится 25 ₽: среднее по двум строкам за 9 и 10 октября. А среднее за все семь календарных дней — 50 / 7 ≈ 7,14 ₽. Этот расчёт предполагает, что данные за все семь дней полные. Для сравнения: обычный AVG(amount) по всей исходной таблице дал бы 20 ₽.

RANGE ограничивает окно, но не создаёт строки для пропущенных дат. Поэтому и в результате запроса остаются только даты, которые есть во входных данных.

Отсутствие строки из-за сбоя загрузки нельзя автоматически приравнивать к нулевым продажам. Иначе календарь сделает результат аккуратным, но неверным.

Перед проверкой формулы по идее надо проверить, что означает одна строка таблицы. Для скользящих показателей это напрямую определяет границы расчёта.

Теги:
0
Комментарии0

Дело о длинном тире

Невероятные приключения здравого смысла среди борцов с ИИ

Сатирическая история о творчестве, бдительности и людях, которые точно знают, как сделать лучше.

Осторожно: может пострадать ваш здравый смысл.

Дело о длинном тире

Публикации