In SQL Server, il RANK()
La funzione restituisce il rango di ogni riga all'interno della partizione di un set di risultati. Il grado di una riga è uno più il numero di gradi che precedono la riga.
Sintassi
La sintassi è questa:
RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )
partizione_per_clausola è facoltativo. Divide il set di risultati prodotto dal FROM
clausola in partizioni a cui viene applicata la funzione. Se non specificata, la funzione tratta tutte le righe del set di risultati della query come un unico gruppo.
ordine_per_clausola è obbligatorio. Determina l'ordine dei dati prima dell'applicazione della funzione.
Nota che il OVER
normalmente accetta una clausola rows_or_range_clause , ma quell'argomento non può essere utilizzato con RANK()
funzione.
Esempio 1 – Utilizzo di base
Ecco un esempio di base che mostra l'utilizzo di RANK()
funzione:
SELECT AlbumId, AlbumName, ArtistId, RANK() OVER (ORDER BY ArtistId ASC) 'Rank' FROM Albums;
Risultato:
+-----------+--------------------------+------------+--------+ | AlbumId | AlbumName | ArtistId | Rank | |-----------+--------------------------+------------+--------| | 1 | Powerslave | 1 | 1 | | 7 | Somewhere in Time | 1 | 1 | | 8 | Piece of Mind | 1 | 1 | | 9 | Killers | 1 | 1 | | 10 | No Prayer for the Dying | 1 | 1 | | 2 | Powerage | 2 | 6 | | 19 | All Night Wrong | 3 | 7 | | 20 | The Sixteen Men of Tain | 3 | 7 | | 12 | Big Swing Face | 4 | 9 | | 4 | Ziltoid the Omniscient | 5 | 10 | | 5 | Casualties of Cool | 5 | 10 | | 6 | Epicloud | 5 | 10 | | 3 | Singing Down the Lane | 6 | 13 | | 16 | Long Lost Suitcase | 7 | 14 | | 17 | Praise and Blame | 7 | 14 | | 18 | Along Came Jones | 7 | 14 | | 11 | No Sound Without Silence | 9 | 17 | | 21 | Yo Wassup | 9 | 17 | | 22 | Busted | 9 | 17 | | 13 | Blue Night | 12 | 20 | | 14 | Eternity | 12 | 20 | | 15 | Scandinavia | 12 | 20 | +-----------+--------------------------+------------+--------+
Il nostro obiettivo principale è ArtistId e Classifica colonne. Possiamo vedere che il rango aumenta ogni volta che aumenta ArtistId. Questo perché ordino per ArtistId, quindi ogni nuovo artista otterrà un nuovo grado.
Quando guardiamo il Rank colonna, possiamo vedere parecchi legami. Cioè, alcune righe condividono lo stesso rango. Questo è prevedibile, perché sto ordinando per ArtistId e alcuni valori di ArtistId sono in più di una riga.
Queste righe legate sono ottime per dimostrare come RANK()
lavori. Come accennato, aumenta di uno più il numero di gradi precedenti. Le righe abbinate fanno apparire degli spazi vuoti nei valori della classifica (cioè non sempre si incrementano di 1). Nell'esempio sopra, ci sono alcune lacune. Il primo è dove va da 1 a 6. Poi un altro quando va da 7 a 9, e così via.
Se non vuoi queste lacune, usa DENSE_RANK()
, che funziona allo stesso modo tranne che senza interruzioni. Il rango denso viene calcolato come uno più il numero di distinti classifica i valori che precedono quella riga.
Esempio 2 – Partizioni
Puoi anche dividere i risultati in partizioni. Quando lo fai, il rango viene calcolato rispetto a ciascuna partizione (quindi ricomincia da capo a ogni nuova partizione).
Esempio:
SELECT Genre, AlbumName, ArtistId, RANK() OVER (PARTITION BY Genre ORDER BY ArtistId ASC) 'Rank' FROM Albums INNER JOIN Genres ON Albums.GenreId = Genres.GenreId;
Risultato:
+---------+--------------------------+------------+--------+ | Genre | AlbumName | ArtistId | Rank | |---------+--------------------------+------------+--------| | Country | Singing Down the Lane | 6 | 1 | | Country | Yo Wassup | 9 | 2 | | Country | Busted | 9 | 2 | | Jazz | All Night Wrong | 3 | 1 | | Jazz | The Sixteen Men of Tain | 3 | 1 | | Jazz | Big Swing Face | 4 | 3 | | Pop | Long Lost Suitcase | 7 | 1 | | Pop | Praise and Blame | 7 | 1 | | Pop | Along Came Jones | 7 | 1 | | Pop | No Sound Without Silence | 9 | 4 | | Pop | Blue Night | 12 | 5 | | Pop | Eternity | 12 | 5 | | Pop | Scandinavia | 12 | 5 | | Rock | Powerslave | 1 | 1 | | Rock | Somewhere in Time | 1 | 1 | | Rock | Piece of Mind | 1 | 1 | | Rock | Killers | 1 | 1 | | Rock | No Prayer for the Dying | 1 | 1 | | Rock | Powerage | 2 | 6 | | Rock | Ziltoid the Omniscient | 5 | 7 | | Rock | Casualties of Cool | 5 | 7 | | Rock | Epicloud | 5 | 7 | +---------+--------------------------+------------+--------+
In questo caso partizione per Genere. Ciò fa sì che ogni riga venga classificata solo rispetto alle altre righe nella stessa partizione. Quindi ogni partizione fa ripartire il valore della classifica da 1.
Esempio 3:un esempio di tabellone segnapunti
Ecco un possibile caso d'uso per visualizzare il grado all'utente.
SELECT Player, Score, RANK() OVER (ORDER BY Score Desc) 'Rank' FROM Scoreboard;
Risultato:
+----------+---------+--------+ | Player | Score | Rank | |----------+---------+--------| | Bart | 2010 | 1 | | Burns | 1270 | 2 | | Meg | 1030 | 3 | | Marge | 990 | 4 | | Lisa | 710 | 5 | | Ned | 666 | 6 | | Apu | 350 | 7 | | Homer | 1 | 8 | +----------+---------+--------+
Tuttavia, tieni presente che qualsiasi risultato in parità comporterà lacune nei valori di classifica.
Ecco cosa succede se Lisa eguaglia improvvisamente il punteggio di Bart:
SELECT Player, Score, RANK() OVER (ORDER BY Score Desc) 'Rank' FROM Scoreboard;
Risultato:
+----------+---------+--------+ | Player | Score | Rank | |----------+---------+--------| | Lisa | 2010 | 1 | | Bart | 2010 | 1 | | Burns | 1270 | 3 | | Meg | 1030 | 4 | | Marge | 990 | 5 | | Ned | 666 | 6 | | Apu | 350 | 7 | | Homer | 1 | 8 | +----------+---------+--------+
In questo caso nessuno è classificato al numero 2, perché i primi due giocatori sono in parità al rango 1.
Come accennato, se devi eliminare lacune come questa, usa DENSE_RANK()
.
Esempio 4 – Sostituzione di RANK() con DENSE_RANK()
Ecco di nuovo lo stesso esempio, tranne che questa volta utilizzo DENSE_RANK()
:
SELECT Player, Score, DENSE_RANK() OVER (ORDER BY Score Desc) 'Rank' FROM Scoreboard;
Risultato:
+----------+---------+--------+ | Player | Score | Rank | |----------+---------+--------| | Lisa | 2010 | 1 | | Bart | 2010 | 1 | | Burns | 1270 | 2 | | Meg | 1030 | 3 | | Marge | 990 | 4 | | Ned | 666 | 5 | | Apu | 350 | 6 | | Homer | 1 | 7 | +----------+---------+--------+