sql >> Databasteknik >  >> RDS >> Sqlserver

Hur DENSE_RANK() fungerar i SQL Server

I SQL Server, DENSE_RANK() funktion returnerar rangen för varje rad inom partitionen för en resultatuppsättning. Rangen för en rad är ett plus antalet distinkta rangordningar som kommer före raden.

Denna funktion liknar RANK() , men utan luckorna i rankningsvärdena som kan uppstå med RANK() när band finns i resultatuppsättningen.

Syntax

Syntaxen ser ut så här:

DENSE_RANK ( ) OVER ( [  ] < order_by_clause > )

är valfritt. Den delar resultatuppsättningen som produceras av FROM sats i partitioner som funktionen tillämpas på. Om det inte anges, behandlas alla rader i frågeresultatuppsättningen som en enda grupp.

krävs. Den bestämmer i vilken ordning funktionen tillämpas på raderna i en partition.

Observera att OVER klausul accepterar normalt en , men det argumentet kan inte användas med den här funktionen.

Exempel 1 – Grundläggande användning

Här är ett grundläggande exempel som visar användningen av DENSE_RANK() funktion:

SELECT
  AlbumId,
  AlbumName,
  ArtistId,
  DENSE_RANK() OVER (ORDER BY ArtistId ASC) 'Rank'
FROM Albums;

Resultat:

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

Titta på ArtistId och Rank kolumner. Rangen ökar varje gång ArtistId ökar. Detta beror på att jag beställer via ArtistId, och så att varje ny artist får en ny rang.

Rangordningen förblir densamma för varje artist, oavsett hur många rader som innehåller samma ArtistId, eftersom resultaten är sorterade efter den kolumnen. Till exempel innehåller fem rader samma ArtistId och därför innehåller de också samma rang. Med andra ord, de är alla delade för rang 1.

På många rader råkar rangordningen vara identisk med ArtistId, men detta är bara en slump. Det råkar vara så att ArtistId är en IDENTITY kolumn som börjar med 1 och ökar med 1, vilket också är vad RANK() gör. Du kommer dock att se att de inte är identiska på alla rader. Till exempel hoppar artist-ID från 7 till 9, men rankningen ökar helt enkelt från 7 till 8, och från den tidpunkten innehåller båda kolumnerna olika värden.

Exempel 2 – Partitioner

Du kan också dela upp resultaten i partitioner. När du gör detta beräknas rankningen mot varje partition (så den börjar om igen med varje ny partition).

Exempel:

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;

Resultat:

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

I det här fallet partitionerar jag efter genre. Detta gör att varje rad endast rankas mot de andra raderna i samma partition. Så varje partition gör att rankningsvärdet börjar på 1 igen.

Exempel 3 – Ett exempel på resultattavla

Här är ett möjligt användningsfall för att visa rankningen för användaren.

SELECT  
  Player,
  Score,
  DENSE_RANK() OVER (ORDER BY Score Desc) 'Rank'
FROM Scoreboard;

Resultat:

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

Tänk på att eventuella bundna resultat inte kommer att påverka efterföljande rangordningar. Med andra ord kommer det inte att finnas några luckor i rangvärdet.

Detta förklaras förmodligen bäst med ett exempel:

SELECT  
  Player,
  Score,
  DENSE_RANK() OVER (ORDER BY Score Desc) 'Rank'
FROM Scoreboard;

Resultat:

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

I det här fallet är Lisa och Bart lika på nummer 1. Sedan kommer Burns in på nummer 2 (även om han är den tredje personen).

Om du föredrar att Burns var rankad som nummer 3 i det här fallet (och Meg på 4, och så vidare), använd RANK() funktion istället.

Exempel 4 – Ersätt DENSE_RANK() med RANK()

Här är samma exempel igen, förutom den här gången använder jag RANK() :

SELECT  
  Player,
  Score,
  RANK() OVER (ORDER BY Score Desc) 'Rank'
FROM Scoreboard;

Resultat:

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

  1. Hur man inaktiverar en främmande nyckelbegränsning i SQL Server (T-SQL-exempel)

  2. Kopiera data från Salesforce till SQL Server med Spectral Core

  3. Genererar djupbaserat träd från hierarkiska data i MySQL (inga CTE)

  4. Rekonstruera Standby DB