← К оглавлению занятия

💻 Примеры

📁 Блок: SQL / MySQL / Оконные функции ⏱️ Время изучения: ~90 мин 🎯 Сложность: Продвинутая

⚡ Кратко: примеры

  • Сумма заказов клиента — SUM(...) OVER (PARTITION BY customer_id).
  • Количество заказов клиента — COUNT(*) OVER (PARTITION BY customer_id).
  • Кумулятивная сумма по датам — SUM(...) OVER (ORDER BY sale_date).
  • Скользящее среднее по клиенту — AVG(...) OVER (PARTITION BY ... ORDER BY ...).

Пример 1. Сумма заказов по клиенту

Для каждого заказа выводим сумму всех заказов этого клиента.

SELECT
    order_id,
    customer_id,
    order_amount,
    SUM(order_amount) OVER (PARTITION BY customer_id) AS total_customer_orders
FROM orders;

Пример 2. Количество заказов по клиенту

Аналогично считаем количество строк в группе клиента.

SELECT
    order_id,
    customer_id,
    order_amount,
    COUNT(*) OVER (PARTITION BY customer_id) AS orders_per_customer
FROM orders;

Пример 3. Максимальная цена по всей таблице products

Окно без PARTITION BY охватывает все строки.

SELECT
    product_name,
    list_price,
    MAX(list_price) OVER () AS max_list_price
FROM products;

Пример 4. Разница в процентах от максимальной цены

Доля, на которую цена продукта отличается от максимальной.

SELECT
    product_name,
    list_price,
    (MAX(list_price) OVER () - list_price)
        / MAX(list_price) OVER () * 100 AS pct_below_max
FROM products;

Пример 5. Кумулятивная сумма продаж по датам

ORDER BY sale_date в окне включает накопление от начала до текущей строки.

SELECT
    sale_id,
    sale_date,
    sale_amount,
    SUM(sale_amount) OVER (ORDER BY sale_date) AS cumulative_sales
FROM sales;

Пример 6. Скользящее среднее по клиенту

Для каждого заказа считаем средний чек клиента на текущий момент.

SELECT
    order_id,
    customer_id,
    order_date,
    order_amount,
    AVG(order_amount) OVER (
        PARTITION BY customer_id
        ORDER BY order_date
    ) AS running_avg
FROM orders;

Пример 7. Сравнение с GROUP BY

Оконная функция сохраняет детальные строки:

SELECT
    customer_id,
    order_id,
    order_amount,
    SUM(order_amount) OVER (PARTITION BY customer_id) AS total
FROM orders;

А GROUP BY сворачивает результат:

SELECT
    customer_id,
    SUM(order_amount) AS total
FROM orders
GROUP BY customer_id;