Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come funziona NTILE() in SQL Server

In SQL Server, il NTILE() La funzione consente di distribuire le righe in 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.

Devi semplicemente fornire il numero di gruppi che desideri quando chiami la funzione.

Sintassi

La sintassi è questa:

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

espressione_intera è un'espressione intera positiva che specifica il numero di gruppi in cui deve essere suddivisa ciascuna partizione. Può essere di tipo int o bigint .

è facoltativo. Divide il set di risultati prodotto dal FROM clausola in partizioni a cui viene applicata la funzione.

è obbligatorio. Determina l'ordine in cui NTILE() i valori vengono assegnati alle righe in una partizione. Un numero intero non può rappresentare una colonna quando viene utilizzato in una funzione di classificazione.

Esempio 1 – Utilizzo di base

Ecco un esempio di base che mostra come funziona questa funzione:

SELECT 
  Player,
  Score,
  NTILE(4) OVER (ORDER BY Score DESC) 'NTILE'
FROM Scoreboard;

Risultato:

+----------+---------+---------+
| Player   | Score   | NTILE   |
|----------+---------+---------|
| Bart     | 2010    | 1       |
| Burns    | 1270    | 1       |
| Meg      | 1030    | 2       |
| Marge    | 990     | 2       |
| Lisa     | 710     | 3       |
| Ned      | 666     | 3       |
| Apu      | 350     | 4       |
| Homer    | 1       | 4       |
+----------+---------+---------+

In questo caso ci sono 8 risultati e il valore che fornisco a NTILE() è 4, quindi i valori sono distribuiti uniformemente su 4 gruppi.

Esempio 2:modifica del valore NTILE

Ecco cosa succede se cambio NTILE() valore a 3.

SELECT 
  Player,
  Score,
  NTILE(3) OVER (ORDER BY Score DESC) 'NTILE'
FROM Scoreboard;

Risultato:

+----------+---------+---------+
| Player   | Score   | NTILE   |
|----------+---------+---------|
| Bart     | 2010    | 1       |
| Burns    | 1270    | 1       |
| Meg      | 1030    | 1       |
| Marge    | 990     | 2       |
| Lisa     | 710     | 2       |
| Ned      | 666     | 2       |
| Apu      | 350     | 3       |
| Homer    | 1       | 3       |
+----------+---------+---------+

I risultati sono distribuiti in 3 gruppi. Come ci si potrebbe aspettare, l'ultimo gruppo finisce con solo 2 righe (contro le 3 degli altri gruppi).

Esempio 3:cambiare l'ordine

Il passaggio dall'ordine crescente a quello decrescente di solito risulterà nel NTILE() valori applicati a righe diverse.

SELECT 
  Player,
  Score,
  NTILE(4) OVER (ORDER BY Score DESC) 'NTILE Descending',
  NTILE(4) OVER (ORDER BY Score ASC) 'NTILE Ascending'
FROM Scoreboard
ORDER BY Score DESC;

Risultato:

+----------+---------+--------------------+-------------------+
| Player   | Score   | NTILE Descending   | NTILE Ascending   |
|----------+---------+--------------------+-------------------|
| Bart     | 2010    | 1                  | 4                 |
| Burns    | 1270    | 1                  | 4                 |
| Meg      | 1030    | 2                  | 3                 |
| Marge    | 990     | 2                  | 3                 |
| Lisa     | 710     | 3                  | 2                 |
| Ned      | 666     | 3                  | 2                 |
| Apu      | 350     | 4                  | 1                 |
| Homer    | 1       | 4                  | 1                 |
+----------+---------+--------------------+-------------------+

Tuttavia, ciò dipenderà dal numero di righe presenti nel set di risultati rispetto al numero di NTILE. Ovviamente, se il NTILE() il valore è 1, quindi non ci sarà alcuna differenza.

SELECT 
  Player,
  Score,
  NTILE(1) OVER (ORDER BY Score DESC) 'NTILE Descending',
  NTILE(1) OVER (ORDER BY Score ASC) 'NTILE Ascending'
FROM Scoreboard
ORDER BY Score DESC;

Risultato:

+----------+---------+--------------------+-------------------+
| Player   | Score   | NTILE Descending   | NTILE Ascending   |
|----------+---------+--------------------+-------------------|
| Bart     | 2010    | 1                  | 1                 |
| Burns    | 1270    | 1                  | 1                 |
| Meg      | 1030    | 1                  | 1                 |
| Marge    | 990     | 1                  | 1                 |
| Lisa     | 710     | 1                  | 1                 |
| Ned      | 666     | 1                  | 1                 |
| Apu      | 350     | 1                  | 1                 |
| Homer    | 1       | 1                  | 1                 |
+----------+---------+--------------------+-------------------+

La stessa cosa accadrà se il set di risultati contiene solo una riga, indipendentemente da NTILE() valore:

SELECT 
  Player,
  Score,
  NTILE(4) OVER (ORDER BY Score DESC) 'NTILE Descending',
  NTILE(4) OVER (ORDER BY Score ASC) 'NTILE Ascending'
FROM Scoreboard
WHERE Score > 2000
ORDER BY Score DESC;

Risultato:

+----------+---------+--------------------+-------------------+
| Player   | Score   | NTILE Descending   | NTILE Ascending   |
|----------+---------+--------------------+-------------------|
| Bart     | 2010    | 1                  | 1                 |
+----------+---------+--------------------+-------------------+

Esempio 4 – Partizioni

Puoi usare il PARTITION BY clausola per dividere i risultati in partizioni. Quando lo fai, NTILE() viene applicato a ciascuna partizione.

Esempio:

SELECT 
  TeamName,
  Player,
  Score,
  NTILE(2) OVER (PARTITION BY TeamName ORDER BY Score ASC) 'NTILE'
FROM Scoreboard s
INNER JOIN Team t
ON t.TeamId = s.TeamId;

Risultato:

+------------+----------+---------+-------------------+
| TeamName   | Player   | Score   | NTILE             |
|------------+----------+---------+-------------------|
| Mongrels   | Apu      | 350     | 1                 |
| Mongrels   | Ned      | 666     | 1                 |
| Mongrels   | Meg      | 1030    | 2                 |
| Mongrels   | Burns    | 1270    | 2                 |
| Simpsons   | Homer    | 1       | 1                 |
| Simpsons   | Lisa     | 710     | 1                 |
| Simpsons   | Marge    | 990     | 2                 |
| Simpsons   | Bart     | 2010    | 2                 |
+------------+----------+---------+-------------------+