Перейти к основному содержимому
Модуль 7 · Урок 3 из 427/57 в курсе~12 min
Уроки модуля (3/4)

LAG, LEAD и текущие итоги

LAG и LEAD — две специальные оконные функции, которые дают вам доступ к другие строки того же раздела: предыдущая строка (LAG) или следующий (LEAD) в соответствии с ORDER BY окна. Они являются инструмент перехода для сравнений строк (дельты, вариации, интервалы) и — в сочетании с SUM/AVG/COUNT OVER — для промежуточных итогов.

LAG: предыдущий ряд

SQL
LAG(colonna)            OVER (PARTITION BY p ORDER BY o)
LAG(colonna, n)         OVER (PARTITION BY p ORDER BY o)   -- n righe indietro
LAG(colonna, n, default) OVER (PARTITION BY p ORDER BY o)  -- default se non c'è

Пример: для каждого заказа «дней с момента предыдущего заказа на тот же самый клиент":

SQL
SELECT id,
       customer_id,
       ordered_at,
       ordered_at - LAG(ordered_at) OVER (
         PARTITION BY customer_id ORDER BY ordered_at
       ) AS since_previous_order
FROM   orders
ORDER BY customer_id, ordered_at;

Первый заказ каждого клиента имеет since_previous_order = NULL, потому что в разделе нет «предыдущего».

ВЕДУЩИЙ: следующий ряд

Зеркало LAG. Типично: «время до следующего события», «разница со следующей версией».

SQL
SELECT id, ordered_at,
       LEAD(ordered_at) OVER (PARTITION BY customer_id ORDER BY ordered_at)
         - ordered_at AS to_next
FROM   orders;

Промежуточные итоги: суммируются с OVER

Агрегатные функции (SUM, AVG, COUNT, MAX, MIN) становятся кумулятивно в сочетании с OVER (… ORDER BY …):

SQL
SELECT order_id,
       total,
       SUM(total) OVER (
         PARTITION BY customer_id
         ORDER BY     ordered_at
       ) AS running_total
FROM   …;

Для каждой строки SUM вычисляет сумму всех строк в разделе до эта точка, согласно ORDER BY окна. Результатом является классический «бегущий баланс».

Попробуйте это

Упражнение#sql.m7.l3.e1
Попыток: 0Загрузка…

Для каждого заказа отображаются идентификатор, customer_id,order_at и столбецdays_from_previous, который представляет собой количество целых дней (с FLOOR) между текущим заказом и предыдущим заказом того же клиента, заказанным с помощью order_at. NULL, если предыдущего заказа нет. Заказ по customer_id и order_at.

Загрузка редактора…
Показать подсказку

LAG(ordered_at) OVER (PARTITION BY customer_id ORDER BY order_at) возвращает метку времени предыдущего заказа клиента. Вычтите, чтобы получить ИНТЕРВАЛ, затем преобразуйте в дни.

Решение доступно после 3 попыток

Обзор упражнения

Упражнение#sql.m7.l3.e2
Попыток: 0Загрузка…

Для каждого доставленного заказа (статус = «доставлено») покажите id, customer_id, order_at, order_total (сумма количества * unit_price его позиций) и Running_total (промежуточную сумму итогов по каждому клиенту, заказанному Order_at). Используйте CTE для order_total. Заказ по customer_id и order_at.

Загрузка редактора…
Показать подсказку

CTE вычисляет общую сумму заказа; Функция SUM OVER дает промежуточную сумму на одного клиента с течением времени.

Решение доступно после 3 попыток