In SQL Server, il DENSE_RANK()
La funzione restituisce il rango di ogni riga all'interno della partizione di un set di risultati. Il rango di una riga è uno più il numero di ranghi distinti che precedono la riga.
Questa funzione è simile a RANK()
, ma senza le lacune nei valori di classifica che possono verificarsi con RANK()
quando esistono pareggi nel set di risultati.
Sintassi
La sintassi è questa:
DENSE_RANK ( ) OVER ( [] < order_by_clause > )
FROM
clausola in partizioni a cui viene applicata la funzione. Se non specificato, tutte le righe del set di risultati della query vengono trattate come un unico gruppo.
Nota che il OVER
La clausola normalmente accetta una
Esempio 1 – Utilizzo di base
Ecco un esempio di base che mostra l'utilizzo di DENSE_RANK()
funzione:
SELECT AlbumId, AlbumName, ArtistId, DENSE_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 | 2 | | 19 | All Night Wrong | 3 | 3 | | 20 | The Sixteen Men of Tain | 3 | 3 | | 12 | Big Swing Face | 4 | 4 | | 4 | Ziltoid the Omniscient | 5 | 5 | | 5 | Casualties of Cool | 5 | 5 | | 6 | Epicloud | 5 | 5 | | 3 | Singing Down the Lane | 6 | 6 | | 16 | Long Lost Suitcase | 7 | 7 | | 17 | Praise and Blame | 7 | 7 | | 18 | Along Came Jones | 7 | 7 | | 11 | No Sound Without Silence | 9 | 8 | | 21 | Yo Wassup | 9 | 8 | | 22 | Busted | 9 | 8 | | 13 | Blue Night | 12 | 9 | | 14 | Eternity | 12 | 9 | | 15 | Scandinavia | 12 | 9 | +-----------+--------------------------+------------+--------+
Guarda ArtistId e Classifica colonne. Il grado aumenta ogni volta che l'ID artista aumenta. Questo perché sto ordinando per ArtistId, quindi ogni nuovo artista riceverà un nuovo grado.
La classifica rimane la stessa per ogni artista, indipendentemente dal numero di righe che contengono lo stesso ArtistId, perché i risultati sono ordinati in base a quella colonna. Ad esempio, cinque righe contengono lo stesso ArtistId e quindi contengono anche lo stesso rango. In altre parole, sono tutti a pari merito per il rango 1.
In molte righe, il rango sembra essere identico a ArtistId, ma questa è solo una coincidenza. Succede che ArtistId è un IDENTITY
colonna che inizia da 1 e aumenta di 1, che è anche ciò che è RANK()
fa. Tuttavia, vedrai che non sono identici su tutte le righe. Ad esempio, ArtistId salta da 7 a 9, ma la classifica aumenta semplicemente da 7 a 8 e, da quel momento in poi, entrambe le colonne contengono valori diversi.
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, DENSE_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 | 2 | | Pop | Long Lost Suitcase | 7 | 1 | | Pop | Praise and Blame | 7 | 1 | | Pop | Along Came Jones | 7 | 1 | | Pop | No Sound Without Silence | 9 | 2 | | Pop | Blue Night | 12 | 3 | | Pop | Eternity | 12 | 3 | | Pop | Scandinavia | 12 | 3 | | 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 | 2 | | Rock | Ziltoid the Omniscient | 5 | 3 | | Rock | Casualties of Cool | 5 | 3 | | Rock | Epicloud | 5 | 3 | +---------+--------------------------+------------+--------+
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, DENSE_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 | +----------+---------+--------+
Tieni presente che qualsiasi risultato in parità non influirà sui ranghi successivi. In altre parole, non ci saranno lacune nel valore della classifica.
Questo è probabilmente spiegato meglio con un esempio:
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 | +----------+---------+--------+
In questo caso Lisa e Bart sono in parità al numero 1. Poi arriva Burns al numero 2 (anche se è la terza persona).
Se preferisci che Burns sia al 3° posto in questo caso (e Meg al 4° e così via), usa il RANK()
funzione invece.
Esempio 4 – Sostituzione di DENSE_RANK() con RANK()
Ecco di nuovo lo stesso esempio, tranne che questa volta uso RANK()
:
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 | +----------+---------+--------+