SQL Serverでは、RANK()
関数は、結果セットのパーティション内の各行のランクを返します。行のランクは、1に行の前に来るランクの数を加えたものです。
構文
構文は次のようになります:
RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )
partition_by_clause オプションです。 FROM
によって生成された結果セットを分割します 関数が適用されるパーティションへの句。指定しない場合、関数はクエリ結果セットのすべての行を単一のグループとして扱います。
order_by_clause 必要とされている。関数が適用される前にデータの順序を決定します。
OVER
に注意してください 句は通常、 rows_or_range_clauseを受け入れます 、ただし、その引数はRANK()
では使用できません 機能。
例1-基本的な使用法
RANK()
の使用法を示す基本的な例を次に示します。 機能:
SELECT AlbumId, AlbumName, ArtistId, RANK() OVER (ORDER BY ArtistId ASC) 'Rank' FROM Albums;
結果:
+-----------+--------------------------+------------+--------+ | 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 | +-----------+--------------------------+------------+--------+
私たちの主な焦点は ArtistId です および ランク 列。 ArtistIdが増加するたびにランクが増加することがわかります。これは、ArtistIdで注文しているため、新しいアーティストごとに新しいランクが付けられるためです。
ランク を見ると 列、私たちはかなりの数の関係を見ることができます。つまり、かなりの数の行が同じランクを共有します。 ArtistIdで並べ替えており、一部のArtistId値が複数の行にあるため、これは予想されることです。
これらの結び付けられた行は、RANK()
がどのように機能するかを示すのに最適です。 動作します。前述のように、1に加えて、その前に来たランクの数が増加します。行を結ぶと、ランキング値にギャップが表示されます(つまり、常に1ずつ増えるとは限りません)。上記の例では、かなりの数のギャップがあります。 1つ目は1から6になり、次に7から9になります。
これらのギャップが必要ない場合は、DENSE_RANK()
を使用してください 、ギャップがないことを除いて同じように機能します。密なランクは、1に個別の数を加えたものとして計算されます。 その行の前にあるランク値。
例2–パーティション
結果をパーティションに分割することもできます。これを行うと、ランクは各パーティションに対して計算されます(したがって、新しいパーティションごとに最初からやり直します)。
例:
SELECT Genre, AlbumName, ArtistId, RANK() OVER (PARTITION BY Genre ORDER BY ArtistId ASC) 'Rank' FROM Albums INNER JOIN Genres ON Albums.GenreId = Genres.GenreId;
結果:
+---------+--------------------------+------------+--------+ | 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 | +---------+--------------------------+------------+--------+
この場合、ジャンル別に分割します。これにより、各行は同じパーティション内の他の行に対してのみランク付けされます。したがって、各パーティションにより、ランキング値は再び1から始まります。
例3–スコアボードの例
ユーザーにランクを表示するための考えられる使用例を次に示します。
SELECT Player, Score, RANK() OVER (ORDER BY Score Desc) 'Rank' FROM Scoreboard;
結果:
+----------+---------+--------+ | 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 | +----------+---------+--------+
ただし、結果が同点の場合は、ランキング値にギャップが生じることに注意してください。
リサが突然バートのスコアと一致した場合は、次のようになります。
SELECT Player, Score, RANK() OVER (ORDER BY Score Desc) 'Rank' FROM Scoreboard;
結果:
+----------+---------+--------+ | 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 | +----------+---------+--------+
この場合、最初の2人のプレーヤーはランク1で同点であるため、誰も2位にランク付けされません。
前述のように、このようなギャップを解消する必要がある場合は、DENSE_RANK()
を使用してください 。
例4– RANK()をDENSE_RANK()に置き換える
今回もDENSE_RANK()
を使用することを除いて、同じ例を次に示します。 :
SELECT Player, Score, DENSE_RANK() OVER (ORDER BY Score Desc) 'Rank' FROM Scoreboard;
結果:
+----------+---------+--------+ | 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 | +----------+---------+--------+