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

Функції вікна: рейтинги та підрахунки по групах

Віконна функція – це функція, яка працює з «групою рядків» (вікно), але — на відміну від GROUP BY — не зменшує кількість rows: значення, обчислене у вікні, додається до кожного рядка кінцевий результат.

Це правильний інструмент для рейтингу, прогресивної нумерації, відсотків над сумою групи та багато інших операцій, які є незручними або неможливо з GROUP BY.

Синтаксис: function() OVER (…)

SQL
ROW_NUMBER() OVER (PARTITION BY colonna ORDER BY colonna2)

Компоненти:

  • PARTITION BY — визначає «групи» (наприклад, GROUP BY, але рядки залишатися окремо);
  • ORDER BY всередині OVER(…) — визначає порядок в перегородка.

OVER () (порожні дужки) означає «вся таблиця як одне вікно». Корисно для таких обчислень, як "відсоток від загального".

Ранжирування функцій

SQL
ROW_NUMBER() OVER (PARTITION BY p ORDER BY o)
RANK()       OVER (PARTITION BY p ORDER BY o)
DENSE_RANK() OVER (PARTITION BY p ORDER BY o)

Відмінності (зі значеннями 100, 100, 90, 80):

ФункціяПосади
ROW_NUMBER1, 2, 3, 4 (завжди унікальні)
RANK1, 1, 3, 4 (зв'язки ділять позицію, залишає «прогалини»)
DENSE_RANK1, 1, 2, 3 (рівні ділять позицію, без розривів)

Приклад: рейтинг продуктів за категоріями

SQL
SELECT name,
       category_id,
       price,
       RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS rank
FROM   products
ORDER BY category_id, rank;

Для кожного category_id RANK перезапускається з 1 і впорядковується за спаданням ціна: ви отримуєте рейтинг товарів в межах кожної категорії, в одній постріл.

Прогресивна нумерація

SQL
-- Progressive order number for each customer:
SELECT id,
       customer_id,
       ordered_at,
       ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY ordered_at) AS row_num
FROM   orders
ORDER BY customer_id, row_num;

Перше замовлення кожного клієнта матиме row_num = 1, друге 2 тощо.

Спробуйте

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

Для кожного продукту відобразити назву, ідентифікатор_категорії, ціну та ранг (ранжування за спаданням ціни В МЕЖАХ категорії; використовуйте RANK). Впорядкувати за зростанням category_id і зростанням рангу.

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

PARTITION BY category_id групи, ORDER BY price DESC замовлення всередині групи.

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

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

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

Для кожного замовлення показуйте ідентифікатор, customer_id, ordered_at і row_num (прогресивний ROW_NUMBER на клієнта, упорядкований за зростанням ordered_at). Порядок за customer_id і row_num.

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

ROW_NUMBER завжди є унікальним у розділі.

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