sql >> Databáze >  >> RDS >> Sqlserver

Jak RANK() funguje v SQL Server

V SQL Server, RANK() Funkce vrací pořadí každého řádku v rámci oddílu sady výsledků. Pořadí řádku je jedna plus počet řádků, které jsou před řádkem.

Syntaxe

Syntaxe vypadá takto:

RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )

partition_by_clause je volitelný. Rozdělí výslednou sadu vytvořenou FROM klauzule do oddílů, na které je funkce aplikována. Pokud není zadáno, funkce považuje všechny řádky sady výsledků dotazu za jednu skupinu.

order_by_clause je požadováno. Určuje pořadí dat před aplikací funkce.

Všimněte si, že OVER klauzule normálně přijímá řádky_nebo_rozsah , ale tento argument nelze použít s RANK() funkce.

Příklad 1 – Základní použití

Zde je základní příklad ukazující použití RANK() funkce:

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

Výsledek:

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

Naším hlavním zaměřením je ArtistId a Hodnocení sloupců. Můžeme vidět, že hodnost se zvyšuje pokaždé, když se zvýší ArtistId. Je to proto, že objednávám podle ArtistId, a tak každý nový umělec získá novou hodnost.

Když se podíváme na Pořadí sloupce, můžeme vidět poměrně dost vazeb. To znamená, že několik řádků sdílí stejnou hodnost. Dá se to očekávat, protože objednávám podle ArtistId a některé hodnoty ArtistId jsou ve více než jednom řádku.

Tyto svázané řádky jsou skvělé pro demonstraci RANK() funguje. Jak již bylo zmíněno, zvýší se o jednu plus počet hodností, které byly před ním. Shodné řádky způsobují, že se v hodnotách hodnocení objevují mezery (tj. ne vždy se zvýší o 1). Ve výše uvedeném příkladu je poměrně dost mezer. První je tam, kde jde od 1 do 6. Pak další, když jde od 7 do 9, a tak dále.

Pokud tyto mezery nechcete, použijte DENSE_RANK() , který funguje stejně, ale bez mezer. Husté pořadí se vypočítá jako jedna plus počet odlišných hodnot, které jsou před tímto řádkem.

Příklad 2 – Oddíly

Výsledky můžete také rozdělit do oddílů. Když to uděláte, hodnocení se vypočítá pro každý oddíl (takže s každým novým oddílem začíná znovu).

Příklad:

SELECT
  Genre,
  AlbumName,
  ArtistId,
  RANK() OVER (PARTITION BY Genre ORDER BY ArtistId ASC) 'Rank'
FROM Albums
INNER JOIN Genres 
ON Albums.GenreId = Genres.GenreId;

Výsledek:

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

V tomto případě rozděluji podle žánru. To způsobí, že každý řádek bude hodnocen pouze proti ostatním řádkům ve stejném oddílu. Každý oddíl tedy způsobí, že hodnota hodnocení začne znovu na 1.

Příklad 3 – Příklad hodnotící tabulky

Zde je možný případ použití pro zobrazení hodnocení uživateli.

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

Výsledek:

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

Mějte však na paměti, že jakékoli nerozhodné výsledky budou mít za následek mezery v hodnotách hodnocení.

Co se stane, když Lisa náhle dosáhne Bartova skóre:

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

Výsledek:

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

V tomto případě se nikdo neumístí na 2. místě, protože první dva hráči jsou na 1. místě nerozhodně.

Jak již bylo zmíněno, pokud potřebujete odstranit mezery, jako je tato, použijte DENSE_RANK() .

Příklad 4 – Nahrazení RANK() za DENSE_RANK()

Zde je znovu stejný příklad, ale tentokrát používám DENSE_RANK() :

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

Výsledek:

+----------+---------+--------+
| 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. Výjimka Java Oracle - maximální počet výrazů v seznamu je 1000

  2. Jak určit hodnotu pole, kterou nelze převést na (desítkové, plovoucí, int) v SQL Server

  3. Jak se používají databáze v elektronickém obchodu

  4. Jak vytvořit tabulku Postgres s jedinečným kombinovaným primárním klíčem?