CodeRang
Темы SQL

LAG SQL: значение из предыдущей строки

LAG SQL позволяет обратиться к значению предыдущей строки внутри заданного окна. Разберём синтаксис LAG, связь LAG и LEAD SQL, порядок строк, разбиение на группы и значения на границе окна.

Обновлено · Команда SQL Arena

Что потренируете

  • Получать предыдущее значение через LAG
  • Обращаться к следующей строке через LEAD
  • Считать изменение к прошлому периоду
  • Разделять последовательности через PARTITION BY
  • Задавать значение по умолчанию для первой строки

Пример задачи в тренажёре

Так выглядит задача в SQL Arena: условие, редактор, результат и схема базы.

Пред.След.Случайная
ЗаданиеОтправкиAI Mentor
Посчитайте изменение баланса к предыдущей дате

В member_balances хранится история бонусных баллов участников. Для каждой записи выведите member_id, balance_date и points_change — разницу между текущим количеством баллов и предыдущим значением этого же участника. Для первой записи участника разница должна быть 0. Отсортируйте результат по member_id и balance_date.

Запрос 1PostgreSQLv16
SELECT member_id,
       balance_date,
       points - LAG(points, 1, points) OVER (
         PARTITION BY member_id ORDER BY balance_date
       ) AS points_change
FROM member_balances
ORDER BY member_id, balance_date;
Отправить
Результатstore_membersmember_balances
Ответ принят

Как работает LAG SQL с OVER

LAG(points, 1, points) вызывается как оконная функция. Первый аргумент — значение, которое нужно взять из другой строки. Второй аргумент 1 означает сдвиг на одну строку назад. Третий задаёт результат на границе окна, когда предыдущей строки ещё нет. Здесь в качестве значения по умолчанию используется текущий points, поэтому для первой записи выражение points - points даёт 0.

PARTITION BY member_id создаёт отдельную последовательность для каждого участника. Без него последняя запись одного человека стала бы предыдущей для первой записи следующего, и разница потеряла бы смысл. ORDER BY balance_date внутри OVER определяет именно логический порядок, в котором LAG ищет предыдущую запись. Это не оформление результата, а часть вычисления.

Внешний ORDER BY member_id, balance_date решает другую задачу: задаёт порядок строк, которые увидит пользователь. LEAD работает по той же модели, но смотрит вперёд. Например, через LEAD(balance_date) можно получить дату следующего события и вычислить, сколько времени осталось до него. Поэтому LAG и LEAD удобно применять к динамике метрик, истории покупок, событиям пользователей и последовательным измерениям.

LAG и LEAD SQL отличаются направлением сдвига. LAG возвращает значение из предыдущей строки относительно текущей, а LEAD — из следующей. Какой именно ряд считается предыдущим или следующим, определяет ORDER BY внутри OVER, поэтому без осмысленной сортировки результат сравнения теряет смысл. Необязательный второй аргумент задаёт число строк смещения, а третий — значение, которое возвращается, если нужной строки нет. PARTITION BY позволяет начинать последовательность заново для каждой группы, например для каждого пользователя или счёта.

SQLPostgreSQL v16
SELECT member_id,
       balance_date,
       points - LAG(points, 1, points) OVER (
         PARTITION BY member_id ORDER BY balance_date
       ) AS points_change
FROM member_balances
ORDER BY member_id, balance_date;
Результат запроса
member_idbalance_datepoints_change
12026-09-010
12026-09-0835
12026-09-15-15
22026-09-020
22026-09-0930
22026-09-1640
32026-09-030
32026-09-1030

Ошибки в LAG и LEAD SQL

01

Забыть PARTITION BY

Если данные относятся к разным клиентам, товарам или устройствам, одна общая последовательность смешивает сущности. Тогда первая строка нового участника сравнивается с последней строкой предыдущего участника.

02

Не задать однозначный порядок внутри OVER

LAG зависит от порядка строк. Если у одной сущности несколько записей имеют одинаковое значение в ORDER BY и дополнительного критерия нет, понятие «предыдущая строка» может стать неоднозначным. Порядок должен отражать реальную последовательность данных.

03

Подменять NULL нулём без понимания смысла

По умолчанию LAG возвращает NULL, если предыдущей строки нет. Иногда это правильный результат: предыдущего наблюдения действительно не существует. В нашем примере нужен именно нулевой прирост, поэтому используется третий аргумент, но такое решение нельзя переносить на все задачи автоматически.

Задачи по теме в тренажёре

Трек «Оконные функции от и до»

Следующий уровень начинается там, где предыдущая строка нужна не ради одного вычитания. В SQL Arena есть задачи на дни между покупками, разницу с прошлым показанием, отношение текущей выручки к предыдущей записи и поиск повторного заказа в ограниченном интервале времени. В более сложных сценариях LAG помогает разбить поток событий на пользовательские сессии или определить смену состояния между периодами. Эти задачи показывают, что главная сложность не в синтаксисе функции, а в правильном определении окна и порядка. Для последовательной практики дальше подходит трек «Оконные функции от и до». В тренажёре также доступны ER-диаграммы и EXPLAIN, а AI-ментор может давать подсказки и объяснять ошибки в пределах доступного лимита.

Справочник по теме

Подробные статьи с синтаксисом и примерами в справочнике SQL Arena.

Частые вопросы

Что делает LAG SQL?

LAG возвращает значение из предыдущей строки внутри окна, определённого выражением OVER. Он полезен для расчёта изменений, интервалов и сравнений с прошлым значением.

Как использовать LAG в SQL?

Функцию вызывают как LAG(expression) OVER (ORDER BY ...). При необходимости добавляют PARTITION BY, смещение вторым аргументом и значение по умолчанию третьим.

Чем LAG отличается от LEAD SQL?

LAG смотрит назад относительно текущей строки, а LEAD — вперёд. Обе функции используют порядок строк, заданный в оконном выражении.

Зачем нужен PARTITION BY в LAG?

PARTITION BY делит строки на независимые группы. Благодаря этому предыдущая строка ищется только внутри своей группы, например внутри одного member_id.

Практика LAG и LEAD в SQL

В SQL Arena 1 192 задачи с автопроверкой. Решения проверяются на скрытых данных, поэтому случайно подогнать запрос под несколько видимых строк недостаточно. Можно работать в PostgreSQL, MySQL, ClickHouse и BigQuery прямо в браузере; сложные задачи открываются в Premium, а 292 задачи доступны бесплатно без карты.

Практиковать LAG и LEAD