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

💻 Примеры

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

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

  • Нумерация строк по дате — ROW_NUMBER() OVER (ORDER BY SaleDate).
  • Ранг по отделам — RANK() OVER (PARTITION BY DepartmentID ORDER BY SaleAmount DESC).
  • Ранг без пропусков — DENSE_RANK() OVER (ORDER BY SaleAmount DESC).
  • Разделение на группы — NTILE(3) OVER (ORDER BY SaleAmount).

Пример 1. ROW_NUMBER() — нумерация строк по дате

Присвоить уникальный номер каждой строке в таблице продаж, упорядоченной по дате.

SELECT
    SaleID,
    SaleDate,
    SaleAmount,
    ROW_NUMBER() OVER (ORDER BY SaleDate) AS RowNum
FROM Sales;

Результат:

SaleIDSaleDateSaleAmountRowNum
12024-01-011001
22024-01-021502
32024-01-032003

Пример 2. RANK() — ранг внутри отдела

Присвоить ранг продажам внутри каждого отдела. При одинаковой сумме продаж строки получают одинаковый ранг, следующий ранг пропускается.

SELECT
    ProductID,
    DepartmentID,
    SaleAmount,
    RANK() OVER (PARTITION BY DepartmentID ORDER BY SaleAmount DESC) AS Rank
FROM ProductSales;

Результат:

ProductIDDepartmentIDSaleAmountRank
1103001
2103001
3102003
4205001
5204002

Пример 3. DENSE_RANK() — ранг без пропусков

Ранжировать продукты по убыванию суммы продаж без пропусков значений.

SELECT
    ProductID,
    SaleAmount,
    DENSE_RANK() OVER (ORDER BY SaleAmount DESC) AS DenseRank
FROM ProductSales;

Результат:

ProductIDSaleAmountDenseRank
45001
54002
13003
23003
32004

Проверить по документации: таблица результата упорядочена по SaleAmount DESC, чтобы соответствовать выражению OVER (ORDER BY SaleAmount DESC). В исходном конспекте пример результата выглядит несогласованным с сортировкой.

Пример 4. NTILE() — разделение на группы

Разделить все продажи на 3 группы по возрастанию суммы.

SELECT
    SaleID,
    SaleAmount,
    NTILE(3) OVER (ORDER BY SaleAmount) AS Quartile
FROM Sales;

Результат:

SaleIDSaleAmountQuartile
11001
22001
33002
44002
55003