Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Funktionsweise von DENSE_RANK() in SQL Server

In SQL Server der DENSE_RANK() Die Funktion gibt den Rang jeder Zeile innerhalb der Partition einer Ergebnismenge zurück. Der Rang einer Reihe ist eins plus die Anzahl der unterschiedlichen Ränge, die vor der Reihe stehen.

Diese Funktion ähnelt RANK() , aber ohne die Lücken in den Ranking-Werten, die bei RANK() auftreten können wenn Bindungen in der Ergebnismenge vorhanden sind.

Syntax

Die Syntax lautet wie folgt:

DENSE_RANK ( ) OVER ( [  ] < order_by_clause > )

es ist optional. Es teilt die von FROM erzeugte Ergebnismenge -Klausel in Partitionen, auf die die Funktion angewendet wird. Wenn nicht angegeben, werden alle Zeilen der Abfrageergebnismenge als eine einzige Gruppe behandelt.

erforderlich. Es bestimmt die Reihenfolge, in der die Funktion auf die Zeilen in einer Partition angewendet wird.

Beachten Sie, dass OVER -Klausel akzeptiert normalerweise eine , aber dieses Argument kann mit dieser Funktion nicht verwendet werden.

Beispiel 1 – Grundlegende Verwendung

Hier ist ein einfaches Beispiel, das die Verwendung von DENSE_RANK() zeigt Funktion:

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

Ergebnis:

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

Sehen Sie sich die ArtistId an und Rang Säulen. Der Rang steigt jedes Mal, wenn die ArtistId steigt. Das liegt daran, dass ich nach ArtistId bestelle und somit jeder neue Künstler einen neuen Rang erhält.

Der Rang bleibt bei jedem Künstler gleich, unabhängig davon, wie viele Zeilen dieselbe ArtistId enthalten, da die Ergebnisse nach dieser Spalte geordnet sind. Beispielsweise enthalten fünf Zeilen dieselbe ArtistId und daher auch denselben Rang. Mit anderen Worten, sie sind alle gleichauf auf Rang 1.

In vielen Zeilen ist der Rang zufällig identisch mit der ArtistId, aber das ist nur ein Zufall. Es ist einfach so, dass die ArtistId eine IDENTITY ist Spalte, die bei 1 beginnt und um 1 erhöht wird, was auch RANK() ist tut. Sie werden jedoch sehen, dass sie nicht in allen Zeilen identisch sind. Beispielsweise springt die ArtistId von 7 auf 9, aber der Rang erhöht sich einfach von 7 auf 8, und von diesem Punkt an enthalten beide Spalten unterschiedliche Werte.

Beispiel 2 – Partitionen

Sie können die Ergebnisse auch in Partitionen aufteilen. Wenn Sie dies tun, wird der Rang für jede Partition berechnet (also beginnt er mit jeder neuen Partition von vorne).

Beispiel:

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;

Ergebnis:

+---------+--------------------------+------------+--------+
| 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 diesem Fall partitioniere ich nach Genre. Dadurch wird jede Zeile nur mit den anderen Zeilen in derselben Partition verglichen. Jede Partition bewirkt also, dass der Ranking-Wert wieder bei 1 beginnt.

Beispiel 3 – Ein Anzeigerbeispiel

Hier ist ein möglicher Anwendungsfall, um dem Benutzer den Rang anzuzeigen.

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

Ergebnis:

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

Denken Sie daran, dass alle unentschiedenen Ergebnisse die nachfolgenden Ränge nicht beeinflussen. Mit anderen Worten, es gibt keine Lücken im Rangwert.

Dies lässt sich wahrscheinlich am besten an einem Beispiel erklären:

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

Ergebnis:

+----------+---------+--------+
| 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 diesem Fall liegen Lisa und Bart auf Platz 1. Dann kommt Burns auf Platz 2 (obwohl er die dritte Person ist).

Wenn Sie es vorziehen, dass Burns in diesem Fall auf Platz 3 rangiert (und Meg auf Platz 4 usw.), verwenden Sie den RANK() funktionieren stattdessen.

Beispiel 4 – Ersetzen von DENSE_RANK() durch RANK()

Hier ist noch einmal dasselbe Beispiel, außer dass ich dieses Mal RANK() verwende :

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

Ergebnis:

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