NTILE (Transact-SQL)
将有序分区中的行分发到指定数目的组中。各个组有编号,编号从一开始。对于每一个行,NTILE 将返回此行所属的组的编号。
语法
NTILE (integer_expression) OVER ( [ <partition_by_clause> ] < order_by_clause > )
参数
integer_expression
一个正整数常量表达式,用于指定每个分区必须被划分成的组数。integer_expression 的类型可以为 int 或 bigint。<partition_by_clause>
将 FROM 子句生成的结果集划分成 RANK 函数适用的分区。若要了解 PARTITION BY 语法,请参阅 OVER 子句 (Transact-SQL)。<order_by_clause>
确定 NTILE 值分配到分区中各行的顺序。有关详细信息,请参阅 ORDER BY 子句 (Transact-SQL)。当在排名函数中使用 <order_by_clause> 时,不能用整数表示列。
返回类型
bigint
注释
如果分区的行数不能被 integer_expression 整除,则将导致一个成员有两种大小不同的组。按照 OVER 子句指定的顺序,较大的组排在较小的组前面。例如,如果总行数是 53,组数是 5,则前三个组每组包含 11 行,其余两个组每组包含 10 行。另一方面,如果总行数可被组数整除,则行数将在组之间平均分布。例如,如果总行数为 50,有五个组,则每组将包含 10 行。
示例
A. 将行分为组
以下示例将行分成四组。由于总行数不能被组数整除,因此第一个组将包含四行,其余每组包含三行。
USE AdventureWorks2008R2;
GO
SELECT p.FirstName, p.LastName
,NTILE(4) OVER(ORDER BY SalesYTD DESC) AS 'Quartile'
,s.SalesYTD, a.PostalCode
FROM Sales.SalesPerson s
INNER JOIN Person.Person p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address 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
(14 row(s) affected)
B. 使用 PARTITION BY 划分结果集
以下示例将 PARTITION BY 参数添加到示例 A 中的代码。首先按 PostalCode 将行分区,然后在每个 PostalCode 内将行分成四个组。该示例还声明一个变量 @NTILE_Var 并使用该变量指定 integer_expression 参数的值。
USE AdventureWorks2008R2;
GO
DECLARE @NTileVar int = 4;
SELECT p.FirstName, p.LastName
,NTILE(@NTileVar) OVER(PARTITION BY PostalCode ORDER BY SalesYTD DESC) AS 'Quartile'
,s.SalesYTD, a.PostalCode
FROM Sales.SalesPerson s
INNER JOIN Person.Person p
ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address a
ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0
ORDER BY LastName;
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
(14 row(s) affected)
(14 行受影响)