适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
Azure Synapse Analytics
Analytics Platform System (PDW)
将有序分区中的行分发到指定数目的组中。 各个组有编号,编号从一开始。 对于每一行, NTILE 返回行所属的组数。
语法
NTILE (integer_expression) OVER ( [ <partition_by_clause> ] <order_by_clause> )
参数
integer_expression
一个正整数表达式,指定每个分区必须划分到其中的组数。 integer_expression 可以是 int 或 bigint 类型 。
partition_by_clause<>
将 FROM 子句和 JOIN、APPLY、PIVOT 子句生成的结果集除为应用函数的分区。
PARTITION BY有关语法,请参阅 SELECT - OVER 子句。
order_by_clause<>
确定将值分配给分区中的行的顺序 NTILE 。 在排名函数中使用order_by_clause>时<,整数不能表示列。
返回类型
bigint
备注
如果分区中的行数因 integer_expression不可见,这会导致由一个成员组成的两个大小组。 较大的组按子句指定的 OVER 顺序出现在较小的组之前。 例如,如果总行数为 53,组数为 5,则前三个组有 11 行,其余两个组各有 10 行。 另一方面,如果行总数由组数分割,则行在组之间均匀分布。 例如,如果总行数为 50,并且有五个组,则每个存储桶包含 10 行。
NTILE 是不确定的。 有关详细信息,请参阅 “确定性”和“不确定”函数。
示例
本文中的代码示例使用 AdventureWorks2022 或 AdventureWorksDW2022 示例数据库,可以从 Microsoft SQL Server 示例和社区项目 主页下载该数据库。
注释
在以下示例中, CONVERT 函数用于将数据 SalesYTD 格式化为货币。
A. 将行划分为组
下面的示例根据员工的年初至今销售额将行分到四个员工组中。 由于总行数与组数不可见,前两个组有四行,其余组各有三行。
USE AdventureWorks2022;
GO
SELECT p.FirstName,
p.LastName,
NTILE(4) OVER (ORDER BY SalesYTD DESC) AS Quartile,
CONVERT (NVARCHAR (20), s.SalesYTD, 1) AS SalesYTD,
a.PostalCode
FROM Sales.SalesPerson AS s
INNER JOIN Person.Person AS p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a
ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0;
GO
结果集如下。
FirstName LastName Quartile SalesYTD PostalCode
------------- --------------------- --------- -------------- ----------
Linda Mitchell 1 4,251,368.55 98027
Jae Pak 1 4,116,871.23 98055
Michael Blythe 1 3,763,178.18 98027
Jillian Carson 1 3,189,418.37 98027
Ranjit Varkey Chudukatil 2 3,121,616.32 98055
José Saraiva 2 2,604,540.72 98055
Shu Ito 2 2,458,535.62 98055
Tsvi Reiter 2 2,315,185.61 98027
Rachel Valdez 3 1,827,066.71 98055
Tete Mensa-Annan 3 1,576,562.20 98055
David Campbell 3 1,573,012.94 98055
Garrett Vargas 4 1,453,719.47 98027
Lynn Tsoflias 4 1,421,810.92 98055
Pamela Ansman-Wolfe 4 1,352,577.13 98027
B. 使用 PARTITION BY 将结果集除以
以下示例将 PARTITION BY 参数添加到示例 A 中的代码。首先按 PostalCode 将行分区,然后在每个 PostalCode 内将行分成四个组。 该示例还声明一个变量 @NTILE_Var 并使用该变量指定 integer_expression 参数的值。
USE AdventureWorks2022;
GO
DECLARE @NTILE_Var AS INT = 4;
SELECT p.FirstName,
p.LastName,
NTILE(@NTILE_Var) OVER (PARTITION BY PostalCode ORDER BY SalesYTD DESC) AS Quartile,
CONVERT (NVARCHAR (20), s.SalesYTD, 1) AS SalesYTD,
a.PostalCode
FROM Sales.SalesPerson AS s
INNER JOIN Person.Person AS p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a
ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0;
GO
结果集如下。
FirstName LastName Quartile SalesYTD PostalCode
------------ -------------------- -------- ------------ ----------
Linda Mitchell 1 4,251,368.55 98027
Michael Blythe 1 3,763,178.18 98027
Jillian Carson 2 3,189,418.37 98027
Tsvi Reiter 2 2,315,185.61 98027
Garrett Vargas 3 1,453,719.47 98027
Pamela Ansman-Wolfe 4 1,352,577.13 98027
Jae Pak 1 4,116,871.23 98055
Ranjit Varkey Chudukatil 1 3,121,616.32 98055
José Saraiva 2 2,604,540.72 98055
Shu Ito 2 2,458,535.62 98055
Rachel Valdez 3 1,827,066.71 98055
Tete Mensa-Annan 3 1,576,562.20 98055
David Campbell 4 1,573,012.94 98055
Lynn Tsoflias 4 1,421,810.92 98055
示例:Azure Synapse Analytics 和 Analytics Platform System (PDW)
C. 将行划分为组
以下示例使用 NTILE 函数根据 2003 年分配的销售配额将一组销售人员划分为四个组。 由于总行数与组数不可见,因此第一个组有五行,其余组各有四行。
-- Uses AdventureWorks
SELECT e.LastName,
NTILE(4) OVER (ORDER BY SUM(SalesAmountQuota) DESC) AS Quartile,
CONVERT (VARCHAR (13), SUM(SalesAmountQuota), 1) AS SalesQuota
FROM dbo.DimEmployee AS e
INNER JOIN dbo.FactSalesQuota AS sq
ON e.EmployeeKey = sq.EmployeeKey
WHERE sq.CalendarYear = 2003
AND SalesTerritoryKey IS NOT NULL
AND SalesAmountQuota <> 0
GROUP BY e.LastName
ORDER BY Quartile, e.LastName;
结果集如下。
LastName Quartile SalesYTD
----------------- -------- ------------
Blythe 1 4,716,000.00
Carson 1 4,350,000.00
Mitchell 1 4,682,000.00
Pak 1 5,142,000.00
Varkey Chudukatil 1 2,940,000.00
Ito 2 2,644,000.00
Saraiva 2 2,293,000.00
Vargas 2 1,617,000.00
Ansman-Wolfe 3 1,183,000.00
Campbell 3 1,438,000.00
Mensa-Annan 3 1,481,000.00
Valdez 3 1,294,000.00
Abbas 4 172,000.00
Albert 4 651,000.00
Jiang 4 544,000.00
Tsoflias 4 867,000.00
D. 使用 PARTITION BY 将结果集除以
以下示例将 PARTITION BY 参数添加到示例 A 中的代码。这些行首先被分区 SalesTerritoryCountry ,然后划分为每个 SalesTerritoryCountry组中的两个组。
OVER子ORDER BY句对结果集进行排序NTILE和ORDER BYSELECT语句排序。
-- Uses AdventureWorks
SELECT e.LastName,
NTILE(2) OVER (PARTITION BY e.SalesTerritoryKey ORDER BY SUM(SalesAmountQuota) DESC) AS Quartile,
CONVERT (VARCHAR (13), SUM(SalesAmountQuota), 1) AS SalesQuota,
st.SalesTerritoryCountry
FROM dbo.DimEmployee AS e
INNER JOIN dbo.FactSalesQuota AS sq
ON e.EmployeeKey = sq.EmployeeKey
INNER JOIN dbo.DimSalesTerritory AS st
ON e.SalesTerritoryKey = st.SalesTerritoryKey
WHERE sq.CalendarYear = 2003
GROUP BY e.LastName, e.SalesTerritoryKey, st.SalesTerritoryCountry
ORDER BY st.SalesTerritoryCountry, Quartile;
结果集如下。
LastName Quartile SalesYTD SalesTerritoryCountry
----------------- -------- -------------- ------------------
Tsoflias 1 867,000.00 Australia
Saraiva 1 2,293,000.00 Canada
Varkey Chudukatil 1 2,940,000.00 France
Valdez 1 1,294,000.00 Germany
Alberts 1 651,000.00 NA
Jiang 1 544,000.00 NA
Pak 1 5,142,000.00 United Kingdom
Mensa-Annan 1 1,481,000.00 United States
Campbell 1 1,438,000.00 United States
Reiter 1 2,768,000.00 United States
Blythe 1 4,716,000.00 United States
Carson 1 4,350,000.00 United States
Mitchell 1 4,682,000.00 United States
Vargas 2 1,617,000.00 Canada
Abbas 2 172,000.00 NA
Ito 2 2,644,000.00 United States
Ansman-Wolfe 2 1,183,000.00 United States