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

💻 Примеры

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

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

  • Минимум, максимум и среднее по заказу — MIN/MAX/AVG(...) OVER (PARTITION BY order_id).
  • Сумма заказа — SUM(quantity * unit_cost) OVER (PARTITION BY order_id).
  • Количество строк в группе — COUNT(*) OVER (PARTITION BY ...).
  • Кумулятивная сумма — SUM(...) OVER (ORDER BY date_received).
  • Кумулятивная сумма по группе — SUM(...) OVER (PARTITION BY ... ORDER BY ...).

Пример 1. Минимум, максимум и среднее по заказу

Для каждого заказа выводим минимальную, максимальную и среднюю цену единицы товара.

SELECT
    order_id,
    unit_cost,
    MIN(unit_cost) OVER (PARTITION BY order_id) AS min_unit_cost,
    MAX(unit_cost) OVER (PARTITION BY order_id) AS max_unit_cost,
    AVG(unit_cost) OVER (PARTITION BY order_id) AS avg_unit_cost
FROM purchase_order_details;

Пример 2. Уникальные строки из предыдущего запроса

Оконные функции дублируют результат в каждую строку заказа. DISTINCT оставляет только уникальные комбинации.

SELECT DISTINCT
    order_id,
    MIN(unit_cost) OVER (PARTITION BY order_id) AS min_unit_cost,
    MAX(unit_cost) OVER (PARTITION BY order_id) AS max_unit_cost,
    AVG(unit_cost) OVER (PARTITION BY order_id) AS avg_unit_cost
FROM purchase_order_details;

Пример 3. Суммарная стоимость заказа

Сначала считаем стоимость строки, затем сумму по заказу окном.

SELECT
    order_id,
    product_id,
    quantity,
    unit_cost,
    quantity * unit_cost AS line_total,
    SUM(quantity * unit_cost) OVER (PARTITION BY order_id) AS order_total
FROM purchase_order_details;

Пример 4. Тот же результат через GROUP BY

GROUP BY сворачивает результат до одной строки на заказ.

SELECT
    order_id,
    SUM(quantity * unit_cost) AS order_total
FROM purchase_order_details
GROUP BY order_id;

Пример 5. Количество продуктов в заказе с учётом статуса

Считаем строки в окне, разбитом по заказу и статусу инвентаризации.

SELECT
    order_id,
    posted_to_inventory,
    product_id,
    COUNT(*) OVER (PARTITION BY order_id, posted_to_inventory) AS products_count
FROM purchase_order_details;

Пример 6. Кумулятивное количество товаров по дате

Накопление идёт по дате получения.

SELECT
    purchase_order_id,
    date_received,
    quantity,
    SUM(quantity) OVER (ORDER BY date_received) AS cumulative_quantity
FROM purchase_order_details;

Пример 7. Кумулятивная выручка по дате для каждого продукта

Накопление внутри каждого продукта.

SELECT
    product_id,
    date_received,
    quantity * unit_cost AS revenue,
    SUM(quantity * unit_cost) OVER (
        PARTITION BY product_id
        ORDER BY date_received
    ) AS cumulative_revenue
FROM purchase_order_details;