sql >> Database >  >> RDS >> Sqlserver

Hoe RANK() werkt in SQL Server

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

Syntaxis

De syntaxis gaat als volgt:

RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )

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

order_by_clause Is benodigd. Het bepaalt de volgorde van de gegevens voordat de functie wordt toegepast.

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

Voorbeeld 1 – Basisgebruik

Hier is een eenvoudig voorbeeld dat het gebruik van de RANK() . laat zien functie:

SELECT
  AlbumId,
  AlbumName,
  ArtistId,
  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          | 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     |
+-----------+--------------------------+------------+--------+

Onze belangrijkste focus is de ArtistId en Rang kolommen. We kunnen zien dat de rangorde elke keer dat de ArtistId toeneemt, toeneemt. Dit komt omdat ik bestel op ArtistId, en dus krijgt elke nieuwe artiest een nieuwe rang.

Als we kijken naar de Rank kolom zien we nogal wat verbanden. Dat wil zeggen, nogal wat rijen delen dezelfde rangorde. Dit is te verwachten, omdat ik bestel op ArtistId en sommige ArtistId-waarden in meer dan één rij staan.

Deze gebonden rijen zijn geweldig om te laten zien hoe RANK() werken. Zoals vermeld, wordt het verhoogd met één plus het aantal rangen dat ervoor kwam. Gebonden rijen veroorzaken hiaten in de rangschikkingswaarden (d.w.z. ze worden niet altijd met 1) verhoogd. In bovenstaand voorbeeld zijn er nogal wat hiaten. De eerste is waar het van 1 naar 6 gaat. Dan nog een wanneer het van 7 naar 9 gaat, enzovoort.

Als u deze hiaten niet wilt, gebruikt u DENSE_RANK() , die op dezelfde manier werkt, behalve zonder gaten. De dichte rangorde wordt berekend als één plus het aantal verschillende rangschik waarden die voor die rij komen.

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,
  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          | 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 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,
  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 echter rekening mee dat gelijklopende resultaten resulteren in hiaten in de rangschikkingswaarden.

Dit is wat er gebeurt als Lisa plotseling overeenkomt met de score van Bart:

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

In dit geval staat niemand op nummer 2, omdat de eerste twee spelers gelijk staan ​​op rang 1.

Zoals gezegd, als u hiaten zoals deze wilt wegwerken, gebruikt u DENSE_RANK() .

Voorbeeld 4 – RANK() vervangen door DENSE_RANK()

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

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

  1. Krijg laatste insert-ID na een voorbereide insert met PDO

  2. SQL Server AlwaysOn (Beschikbaarheidsgroep) Architectuur en stapsgewijze installatie -2

  3. Corrupte database herstellen postgresql

  4. LIKE-query op elementen van platte jsonb-array