NTILE (Transact-SQL)

Si applica a: SQL Server Database SQL di Azure Istanza gestita di SQL di Azure Azure Synapse Analytics Piattaforma di strumenti analitici (PDW)

Distribuisce le righe di una partizione ordinata in un numero specificato di gruppi. I gruppi sono numerati a partire da 1. Per ogni riga, NTILE restituisce il numero del gruppo a cui appartiene la riga.

Convenzioni relative alla sintassi Transact-SQL

Sintassi

NTILE (integer_expression) OVER ( [ <partition_by_clause> ] < order_by_clause > )  

Argomenti

integer_expression
Espressione intera positiva che specifica il numero di gruppi in cui suddividere ogni partizione. integer_expression può essere di tipo int o bigint.

<partition_by_clause>
Suddivide il set di risultati generato dalla clausola FROM in partizioni alle quali viene applicata la funzione. Per la sintassi PARTITION BY, vedere Clausola OVER (Transact-SQL).

<order_by_clause>
Determina l'ordine di assegnazione dei valori NTILE alle righe in una partizione. Una colonna non può essere rappresentata da un valore intero quando si usa <order_by_clause> in una funzione di rango.

Tipi restituiti

bigint

Osservazioni:

Se il numero di righe in una partizione non è divisibile per integer_expression vengono creati gruppi di due dimensioni che differiscono per un membro. I gruppi più grandi precedono i gruppi più piccoli nell'ordine specificato dalla clausola OVER. Se ad esempio il numero totale di righe è 53 e il numero di gruppi è 5, i primi 3 gruppi includeranno 11 righe e i 2 gruppi rimanenti 10 righe ognuno. Se invece il numero totale delle righe è divisibile per il numero di gruppi, le righe verranno distribuite uniformemente tra di essi. Se ad esempio il numero totale di righe è 50 e sono disponibili 5 gruppi, ogni bucket conterrà 10 righe.

NTILE è non deterministico. Per altre informazioni, vedere Funzioni deterministiche e non deterministiche.

Esempi

R. Divisione di righe in gruppi

Nell'esempio seguente vengono divise le righe in quattro gruppi di dipendenti in base alle relative vendite da inizio anno. Poiché il numero totale di righe non è divisibile per il numero di gruppi, i primi due gruppi conterranno 4 righe e gli altri 3 righe ognuno.

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  

Il set di risultati è il seguente.

  
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. Divisione del set di risultati tramite PARTITION BY

Nell'esempio seguente viene aggiunto l'argomento PARTITION BY al codice dell'esempio A. Le righe vengono prima partizionate in base a PostalCode e quindi divise in quattro gruppi in ogni PostalCode. Nell'esempio viene anche dichiarata una variabile @NTILE_Var che viene usata per specificare il valore del parametro integer_expression.

USE AdventureWorks2022;  
GO  
DECLARE @NTILE_Var 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  

Il set di risultati è il seguente.

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)  

Esempi: Azure Synapse Analytics e Piattaforma di strumenti analitici (PDW)

C. Divisione di righe in gruppi

L'esempio seguente usa la funzione NTILE per dividere un set di venditori in quattro gruppi in base alle quote di vendite loro assegnate per l'anno 2003. Poiché il numero totale di righe non è divisibile per il numero di gruppi, il primo gruppo conterrà cinque righe e gli altri conterranno quattro righe ciascuno.

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

Il set di risultati è il seguente.

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. Divisione del set di risultati tramite PARTITION BY

Nell'esempio seguente viene aggiunto l'argomento PARTITION BY al codice dell'esempio A. Le righe vengono prima partizionate in base a SalesTerritoryCountry e quindi divise in quattro gruppi in ogni SalesTerritoryCountry. Si noti che ORDER BY nella clausola OVER ordina NTILE e ORDER BY dell'istruzione SELECT ordina il set di risultati.

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

Il set di risultati è il seguente.

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

Vedi anche

RANK (Transact-SQL)
DENSE_RANK (Transact-SQL)
ROW_NUMBER (Transact-SQL)
Funzioni di classificazione (Transact-SQL)
Funzioni predefinite (Transact-SQL)