sql >> Database >  >> RDS >> Sqlserver

Hoe DENSE_RANK() werkt in SQL Server

In SQL Server, de DENSE_RANK() functie retourneert de rangorde van elke rij binnen de partitie van een resultaatset. De rangorde van een rij is één plus het aantal verschillende rangen dat voor de rij komt.

Deze functie is vergelijkbaar met RANK() , maar zonder de hiaten in de rangschikkingswaarden die kunnen optreden met RANK() wanneer er verbanden zijn in de resultaatset.

Syntaxis

De syntaxis gaat als volgt:

DENSE_RANK ( ) OVER ( [  ] < order_by_clause > )

is optioneel. Het verdeelt de resultatenset geproduceerd door de FROM clausule in partities waarop de functie wordt toegepast. Indien niet opgegeven, worden alle rijen van de queryresultatenset als één groep behandeld.

Is benodigd. Het bepaalt de volgorde waarin de functie van toepassing is op de rijen in een partitie.

Merk op dat de OVER clausule accepteert normaal gesproken een , maar dat argument kan niet worden gebruikt met deze functie.

Voorbeeld 1 – Basisgebruik

Hier is een eenvoudig voorbeeld van het gebruik van de DENSE_RANK() functie:

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

Resultaat:

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

Kijk naar de ArtistId en Rang kolommen. Elke keer dat de ArtistId stijgt, wordt de rangorde verhoogd. Dit komt omdat ik bestel op ArtistId, en dus krijgt elke nieuwe artiest een nieuwe rang.

De rangorde blijft bij elke artiest hetzelfde, ongeacht hoeveel rijen dezelfde ArtistId bevatten, omdat de resultaten op die kolom zijn geordend. Zo bevatten vijf rijen dezelfde ArtistId en dus ook dezelfde rangorde. Met andere woorden, ze staan ​​allemaal op gelijke hoogte voor rang 1.

In veel rijen is de rangorde identiek aan de ArtistId, maar dit is gewoon toeval. Toevallig is de ArtistId een IDENTITY kolom die begint bij 1 en wordt verhoogd met 1, wat ook is wat RANK() . is doet. U zult echter zien dat ze niet in alle rijen identiek zijn. De ArtistId springt bijvoorbeeld van 7 naar 9, maar de rangorde wordt gewoon verhoogd van 7 naar 8, en vanaf dat moment bevatten beide kolommen verschillende waarden.

Voorbeeld 2 – Partities

U kunt de resultaten ook in partities verdelen. Wanneer je dit doet, wordt de rangorde berekend voor elke partitie (dus begint het opnieuw met elke nieuwe partitie).

Voorbeeld:

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;

Resultaat:

+---------+--------------------------+------------+--------+
| 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 dit geval verdeel ik op genre. Dit zorgt ervoor dat elke rij alleen wordt gerangschikt tegen de andere rijen in dezelfde partitie. Dus elke partitie zorgt ervoor dat de rangordewaarde weer bij 1 begint.

Voorbeeld 3 – Een voorbeeld van een scorebord

Hier is een mogelijke use-case voor het weergeven van de rang aan de gebruiker.

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

Resultaat:

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

Houd er rekening mee dat gelijklopende resultaten de volgende rangen niet beïnvloeden. Met andere woorden, er zullen geen gaten in de rangorde zijn.

Dit kan waarschijnlijk het beste worden uitgelegd met een voorbeeld:

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

Resultaat:

+----------+---------+--------+
| 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 dit geval staan ​​Lisa en Bart gelijk op nummer 1. Dan komt Burns binnen op nummer 2 (ook al is hij de derde persoon).

Als je liever hebt dat Burns in dit geval op nummer 3 stond (en Meg op 4, enzovoort), gebruik dan de RANK() in plaats daarvan functioneren.

Voorbeeld 4 – DENSE_RANK() vervangen door RANK()

Hier is hetzelfde voorbeeld opnieuw, maar deze keer gebruik ik RANK() :

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

Resultaat:

+----------+---------+--------+
| 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. Bereik hiërarchie, ouder-kindrelatie op een effectieve en gemakkelijke manier

  2. Hoe verbinding maken met MS SQL Server met behulp van Inno Setup?

  3. Converteer SQLite naar JSON

  4. Microsoft OLE DB Niet verouderd! Lang leve ADO!