Оконные функции

Смещение: LAG и LEAD

Содержание курса

Ловушка: отсутствие PARTITION BY смешивает строки разных категорий

Самая распространённая ошибка с LAG — забыть PARTITION BY, когда данные содержат несколько смысловых групп.

Предположим, запрос написан так:

SELECT
    category,
    month,
    amount,
    LAG(amount, 1, NULL) OVER (ORDER BY category, month) AS prev_amount
FROM monthly_sales
ORDER BY category, month;

Без PARTITION BY category окно охватывает все шесть строк сразу. После сортировки по category, month они выстраиваются в порядке: Книги-01, Книги-02, Книги-03, Электроника-01, Электроника-02, Электроника-03. LAG для строки «Электроника-01» смотрит на строку непосредственно перед ней в этом глобальном порядке — то есть на «Книги-03» со значением 600.

Результат будет таким:

category month amount prev_amount
Книги 2024-01 500 NULL
Книги 2024-02 700 500
Книги 2024-03 600 700
Электроника 2024-01 1200 600
Электроника 2024-02 900 1200
Электроника 2024-03 1100 900

Строка «Электроника-01» получила prev_amount = 600 — это последнее значение из категории «Книги». Никакой ошибки выполнения не будет: запрос отработает тихо и вернёт правдоподобно выглядящие числа. Обнаружить проблему можно только если знать, что ожидать NULL для первого периода каждой категории.

Исправление одно — добавить PARTITION BY category:

LAG(amount, 1, NULL) OVER (PARTITION BY category ORDER BY month)

Теперь для строки «Электроника-01» окно начинается заново внутри раздела «Электроника», предшественника нет, и LAG честно возвращает NULL.

Практическое правило: если в данных есть смысловые группы (категория, пользователь, регион) и вы хотите смотреть на «предыдущий» элемент внутри группы — PARTITION BY обязателен.

Начать заново?

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

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

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

Проверка решения остаётся отдельным действием.