Модульні уроки (3/4)
LAG, LEAD і поточні підсумки
LAG та LEAD — дві спеціальні віконні функції, які надають вам доступ до
інші рядки того самого розділу: попередній рядок (LAG) або
наступний (LEAD) відповідно до ORDER BY вікна. Вони є
інструмент переходу до порядкового порівняння (дельти, варіації, інтервали)
і — у поєднанні з SUM/AVG/COUNT OVER — для загальних підсумків.
ЛАГ: попередній ряд
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'èПриклад: для кожного замовлення «днів з попереднього замовлення на стільки ж клієнт":
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. Типові: «час до наступної події», «різниця
з наступною версією».
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 …):
SELECT order_id,
total,
SUM(total) OVER (
PARTITION BY customer_id
ORDER BY ordered_at
) AS running_total
FROM …;Для кожного рядка SUM обчислює суму всіх рядків у розділі до
ця точка, відповідно до ORDER BY вікна. Результатом є
класичний «біговий баланс».
Спробуйте
Для кожного замовлення відображаються ідентифікатор, 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 спроб
Повторна вправа
Для кожного доставленого замовлення (статус = 'доставлено') покажіть ідентифікатор, customer_id, ordered_at, order_total (сума кількості * unit_price його рядків-позицій) і running_total (загальний підсумок для клієнта, замовлений ordered_at). Використовуйте CTE для order_total. Порядок за customer_id і ordered_at.
Показати підказку
CTE обчислює загальну суму за замовлення; SUM OVER дає загальну суму для кожного клієнта за певний час.
Рішення доступне після 3 спроб