Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak DENSE_RANK() działa w SQL Server

W SQL Server DENSE_RANK() funkcja zwraca rangę każdego wiersza w ramach partycji zbioru wyników. Ranga wiersza to jeden plus liczba odrębnych rang, które znajdują się przed wierszem.

Ta funkcja jest podobna do RANK() , ale bez luk w wartościach rankingu, które mogą wystąpić przy użyciu RANK() gdy w zestawie wyników istnieją powiązania.

Składnia

Składnia wygląda tak:

DENSE_RANK ( ) OVER ( [  ] < order_by_clause > )

jest opcjonalne. Dzieli zestaw wyników utworzony przez FROM klauzuli na przegrody, do których funkcja jest stosowana. Jeśli nie zostanie określony, wszystkie wiersze zestawu wyników zapytania są traktowane jako jedna grupa.

jest wymagane. Określa kolejność, w jakiej funkcja dotyczy wierszy w partycji.

Zauważ, że OVER klauzula normalnie akceptuje , ale ten argument nie może być użyty z tą funkcją.

Przykład 1 – Podstawowe użycie

Oto podstawowy przykład pokazujący użycie DENSE_RANK() funkcja:

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

Wynik:

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

Spójrz na ArtistId i ranking kolumny. Ranga wzrasta za każdym razem, gdy zwiększa się identyfikator ArtistId. To dlatego, że zamawiam przez ArtistId, więc każdy nowy artysta otrzyma nową rangę.

Pozycja pozostaje taka sama dla każdego wykonawcy, niezależnie od tego, ile wierszy zawiera ten sam ArtistId, ponieważ wyniki są uporządkowane według tej kolumny. Na przykład pięć wierszy zawiera ten sam ArtistId, a zatem zawiera również tę samą rangę. Innymi słowy, wszyscy mają remis na 1. miejscu

W wielu rzędach pozycja jest identyczna z ArtistId, ale to tylko zbieg okoliczności. Tak się składa, że ​​ArtistId to IDENTITY kolumna, która zaczyna się od 1 i zwiększa się o 1, co jest również tym, co RANK() robi. Jednak zobaczysz, że nie są one identyczne we wszystkich rzędach. Na przykład ArtistId przeskakuje od 7 do 9, ale pozycja po prostu wzrasta od 7 do 8 i od tego momentu obie kolumny zawierają różne wartości.

Przykład 2 – Partycje

Możesz także podzielić wyniki na partycje. Kiedy to zrobisz, ranga jest obliczana dla każdej partycji (więc zaczyna się od nowa z każdą nową partycją).

Przykład:

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;

Wynik:

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

W tym przypadku dzielę według gatunku. Powoduje to, że każdy wiersz jest klasyfikowany tylko względem innych wierszy w tej samej partycji. Tak więc każda partycja powoduje, że wartość rankingu ponownie zaczyna się od 1.

Przykład 3 – Przykład tablicy wyników

Oto możliwy przypadek użycia do wyświetlania rangi użytkownikowi.

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

Wynik:

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

Pamiętaj, że remis nie wpłynie na kolejne rankingi. Innymi słowy, nie będzie żadnych luk w wartości rangi.

Najlepiej wytłumaczyć to na przykładzie:

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

Wynik:

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

W tym przypadku Lisa i Bart remisują pod numerem 1. Następnie Burns jest pod numerem 2 (mimo że jest trzecią osobą).

Jeśli wolisz, aby Burns był w tym przypadku na 3 miejscu (a Meg na 4 itd.), użyj RANK() funkcja zamiast.

Przykład 4 – zastąpienie DENSE_RANK() RANK()

Oto znowu ten sam przykład, ale tym razem używam RANK() :

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

Wynik:

+----------+---------+--------+
| 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak działa Z WYJĄTKIEM w SQL Server

  2. Instrukcja SQL CASE

  3. Oblicz różnicę czasu między dwoma rzędami

  4. Pięć najważniejszych kwestii dotyczących projektowania indeksu bazy danych w programie SQL Server

  5. warunkowe ograniczenie unikatowe