Уроки модуля (2/4)
Оконные функции: ранжирование и расчеты по группам
Оконная функция — это функция, которая работает с «группой строк».
(окно), но — в отличие от GROUP BY — не уменьшает количество
строки: значение, вычисленное в окне, прикрепляется к каждой строке
окончательный результат.
Это правильный инструмент для ранжирования, прогрессивной нумерации и процентов.
над общей суммой группы и многие другие операции, которые неудобны или
невозможно с GROUP BY.
Синтаксис: function() OVER (…).
ROW_NUMBER() OVER (PARTITION BY colonna ORDER BY colonna2)Компоненты:
PARTITION BY— определяет «группы» (например,GROUP BY, но строки оставайтесь отдельно);ORDER BYвнутриOVER(…)— определяет порядок внутри перегородка.
OVER () (пустые скобки) означает «вся таблица как одно окно».
Полезно для вычислений типа «процент от общего количества».
Функции ранжирования
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_NUMBER | 1, 2, 3, 4 (всегда уникальные) |
RANK | 1, 1, 3, 4 (связи разделяют позицию, оставляют «пробелы») |
DENSE_RANK | 1, 1, 2, 3 (связи делят позицию, без пропусков) |
Пример: рейтинг продукта по категории.
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 и упорядочивается по убыванию
цена: вы получаете рейтинг продуктов внутри каждой категории, в одной
выстрел.
Прогрессивная нумерация
-- 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 и т. д.
Попробуйте это
Для каждого продукта отображается название, идентификатор категории, цена и рейтинг (ранжирование по убыванию цены ВНУТРИ категории; используйте РАНГ). Упорядочите по возрастанию категории_id и возрастанию ранга.
Показать подсказку
РАЗДЕЛЕНИЕ ПО категориям_id групп, ПОРЯДОК ПО цене DESC заказов внутри группы.
Решение доступно после 3 попыток
Обзор упражнения
Для каждого заказа отображаются идентификатор, customer_id, order_at и row_num (прогрессивный ROW_NUMBER для каждого клиента, упорядоченный по возрастанию order_at). Упорядочить по customer_id и row_num.
Показать подсказку
ROW_NUMBER всегда уникален в пределах раздела.
Решение доступно после 3 попыток