共用方式為


NTILE (Transact-SQL)

適用於:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics分析平台系統(PDW)Microsoft Fabric 中的 SQL 資料庫

將排序分割區中的資料列散發到指定數目的群組中。 這些群組從 1 開始編號。 針對每一列, NTILE 傳回該列所屬群組的編號。

Transact-SQL 語法慣例

語法

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 是不確定的。 如需詳細資訊,請參閱 確定性和非確定性函數

範例

本文中的程式碼範例會使用 或AdventureWorks2025AdventureWorksDW2025範例資料庫,您可以從 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 來分割結果集

下列範例會在範例 A 的程式碼中加入 PARTITION BY 引數。資料列會先由 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中分成兩組。 子句中的 ORDER BYOVERNTILEORDER BY 陳述式的 SELECT 對結果集進行排序。

-- 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