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

LAG, LEAD і поточні підсумки

LAG та LEAD — дві спеціальні віконні функції, які надають вам доступ до інші рядки того самого розділу: попередній рядок (LAG) або наступний (LEAD) відповідно до ORDER BY вікна. Вони є інструмент переходу до порядкового порівняння (дельти, варіації, інтервали) і — у поєднанні з SUM/AVG/COUNT OVER — для загальних підсумків.

ЛАГ: попередній ряд

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;

Загальні підсумки: об’єднуються з НАД

Агрегатні функції (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, ordered_at і стовпець days_from_previous, який є кількістю повних днів (з FLOOR) між поточним замовленням і попереднім того самого клієнта, замовленим ordered_at. NULL, якщо попереднього порядку немає. Порядок за customer_id і ordered_at.

Завантаження редактора…
Показати підказку

LAG(ordered_at) OVER (PARTITION BY customer_id ORDER BY ordered_at) повертає мітку часу попереднього замовлення клієнта. Відніміть, щоб отримати INTERVAL, а потім переведіть у дні.

Рішення доступне після 3 спроб

Повторна вправа

вправи#sql.m7.l3.e2
Спроби: 0Завантаження…

Для кожного доставленого замовлення (статус = 'доставлено') покажіть ідентифікатор, customer_id, ordered_at, order_total (сума кількості * unit_price його рядків-позицій) і running_total (загальний підсумок для клієнта, замовлений ordered_at). Використовуйте CTE для order_total. Порядок за customer_id і ordered_at.

Завантаження редактора…
Показати підказку

CTE обчислює загальну суму за замовлення; SUM OVER дає загальну суму для кожного клієнта за певний час.

Рішення доступне після 3 спроб