sql >> データベース >  >> RDS >> Sqlserver

SQL ServerでのRANK()の動作

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

    1. 時系列データベースのスケーリング-TimescaleDBを単純にスケーリングする方法

    2. サーバーのタイムゾーン値「AEST」が認識されないか、複数のタイムゾーンを表します

    3. 給与に対する累積合計と合計合計の両方を計算するためのクエリ

    4. 内部結合は等結合と同じですか?