Функция SQL Server NTILE

В этом руководстве вы узнаете, как использовать функцию SQL Server NTILE() для распределения строк упорядоченного раздела по указанному количеству сегментов.

Введение в функцию SQL Server NTILE()

SQL Server NTILE() — это оконная функция, которая распределяет строки упорядоченного раздела по указанному числу приблизительно равных групп или сегментов. Она назначает каждой группе номер сегмента, начиная с единицы. Для каждой строки в группе функция NTILE() назначает номер сегмента, представляющий группу, к которой принадлежит строка.

Синтаксис функции NTILE() следующий:

NTILE(buckets) OVER(
    [PARTITION BY partition_expression, ... ]
    ORDER BY sort_expression [ASC | DESC], ...
)

Давайте рассмотрим синтаксис подробно:

ведра

Количество сегментов, на которые разделены строки. Сегменты могут быть выражением или подзапросом, результатом которого является положительное целое число. Это не может быть оконная функция.

РАЗДЕЛЕНИЕ ПО пункту

Предложение PARTITION BY распределяет строки результирующего набора по разделам, к которым применяется функция NTILE().

Предложение ORDER BY

Предложение ORDER BY определяет логический порядок строк в каждом разделе, к которому применяется NTILE().

Если количество строк не делится на количество ячеек, функция NTILE() возвращает группы двух размеров с разницей в один. Большие группы всегда идут перед меньшими в порядке, указанном ORDER BY в предложении OVER().

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

Иллюстрация функции SQL Server NTILE()

Следующий оператор создает новую таблицу с именем ntile_demo, в которой хранится 10 целых чисел:

CREATE TABLE sales.ntile_demo(
 v INT NOT NULL
);
INSERT INTO sales.ntile_demo(v) 
VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
SELECT * FROM sales.ntile_demo;

Этот оператор использует функцию NTILE() для разделения десяти строк на три группы:

SELECT 
 v, 
 NTILE(3) OVER(
 ORDER BY v
 ) buckets
FROM 
 sales.ntile_demo;

Вот что получилось:

Функция SQL Server NTILE

Как ясно видно из выходных данных, первая группа состоит из четырех строк, а две другие группы — из трех строк.

Следующий оператор использует функцию NTILE() для распределения строк по пяти группам:

SELECT 
 v, 
 NTILE(5) OVER(
 ORDER BY v
 ) buckets
FROM 
 sales.ntile_demo;

Вывод следующий:

Функция SQL Server NTILE с 5 группами

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

Примеры функций SQL Server NTILE()

Давайте создадим представление для демонстрации функции NTILE().

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

CREATE VIEW sales.vw_netsales_2017 AS
SELECT 
 c.category_name,
 DATENAME(month, o.shipped_date) month, 
 CONVERT(DEC(10, 0), SUM(i.list_price * quantity *(1 - discount))) net_sales
FROM 
 sales.orders o
INNER JOIN sales.order_items i ON i.order_id = o.order_id
INNER JOIN production.products p on p.product_id = i.product_id
INNER JOIN production.categories c on c.category_id = p.category_id
WHERE 
 YEAR(shipped_date) = 2017
GROUP BY
 c.category_name,
 DATENAME(month, o.shipped_date);
SELECT 
    category_name, 
    month,
    net_sales 
FROM 
   sales.vw_netsales_2017 
ORDER BY 
   category_name, 
   net_sales;

Вот результат:

Пример представления SQL Server NTILE

Пример использования функции SQL Server NTILE() для набора результатов запроса

В следующем примере функция NTILE() используется для распределения месяцев по 4 сегментам на основе чистых продаж:

WITH cte_by_month AS(
 SELECT
 month, 
 SUM(net_sales) net_sales
 FROM 
 sales.vw_netsales_2017
 GROUP BY 
 month
)
SELECT
 month, 
 FORMAT(net_sales,'C','en-US') net_sales,
 NTILE(4) OVER(
 ORDER BY net_sales DESC
 ) net_sales_group
FROM 
 cte_by_month;

Вот что получилось:

Функция SQL Server NTILE над результирующим набором

Пример использования функции SQL Server NTILE() для разделов

В этом примере функция NTILE() используется для разделения чистых продаж по месяцам на 4 группы для каждой категории продуктов:

SELECT
 category_name,
 month, 
 FORMAT(net_sales,'C','en-US') net_sales,
 NTILE(4) OVER(
 PARTITION BY category_name
 ORDER BY net_sales DESC
 ) net_sales_group
FROM 
 sales.vw_netsales_2017;

На следующем рисунке показан частичный вывод:

Пример функции SQL Server NTILE для раздела

В этом руководстве вы узнали, как использовать функцию SQL Server NTILE() для распределения строк упорядоченного раздела по указанному количеству сегментов.

Мирослав С.

Автор статей, ИБ-специалист