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

SQLServerのランキング関数

    会社のCEO向けにSQLServerデータベースアプリケーションを設計していて、会社で5番目に高給の従業員を表示する必要があるとします。

    あなたならどうしますか? 1つの解決策は、次のようなクエリを作成することです。

    SELECT EmployeeName
    FROM Employees
    ORDER BY Salary DESC
    OFFSET 4 ROWS
    FETCH FIRST 1 ROWS ONLY;

    上記のクエリは、特にすべての従業員をランク付けする必要がある場合は面倒に見えます。その場合、1つの解決策は、給与の降順で従業員をリストし、次に従業員のインデックスをランクとして使用することです。ただし、複数の従業員が同じ給与を持っていると、事態は複雑になります。それらをどのようにランク付けしますか?

    幸い、SQL Serverには、さまざまな方法でレコードをランク​​付けするために使用できる組み込みのランク付け関数が付属しています。この記事では、SQLサーバーのランキング関数を詳細に紹介し、例を示します。

    SQLServerには4つの異なるタイプのランキング関数があります。

    • ランク()
    • Dense_Rank()
    • 行番号()
    • Ntile()

    SQLServerのすべてのランキング関数にはORDERBY句が必要であることに注意してください。

    各ランキング関数を詳しく見る前に、まず、この記事でランキング関数を説明するために使用するダミーデータを作成しましょう。次のスクリプトを実行します。

    CREATE DATABASE Showroom
    
    Use Showroom
    CREATE TABLE Car
    (
    CarId int identity(1,1) primary key,
    Name varchar(100),
    Make varchar(100),
    Model int ,
    Price int ,
    Type varchar(20)
    )
    
    insert into Car( Name, Make, Model , Price, Type)
    VALUES ('Corrolla','Toyota',2015, 20000,'Sedan'),
    ('Civic','Honda',2018, 25000,'Sedan'),
    ('Passo','Toyota',2012, 18000,'Hatchback'),
    ('Land Cruiser','Toyota',2017, 40000,'SUV'),
    ('Corrolla','Toyota',2011, 17000,'Sedan'),
    ('Vitz','Toyota',2014, 15000,'Hatchback'),
    ('Accord','Honda',2018, 28000,'Sedan'),
    ('7500','BMW',2015, 50000,'Sedan'),
    ('Parado','Toyota',2011, 25000,'SUV'),
    ('C200','Mercedez',2010, 26000,'Sedan'),
    ('Corrolla','Toyota',2014, 19000,'Sedan'),
    ('Civic','Honda',2015, 20000,'Sedan')

    上記のスクリプトでは、1つのテーブルCarを使用してShowroomデータベースを作成します。 Carテーブルには、CarId、Name、Make、Model、Price、Typeの5つの属性があります。

    次に、Carテーブルに12個のダミーレコードを追加しました。

    これで、各ランキング関数が表示されます。

    1。ランク関数

    SQL Serverのrank関数は、ORDERBY句で順序付けられた各レコードにランクを割り当てます。たとえば、Carテーブルで5番目に高価な車を表示する場合は、次のようにランク関数を使用できます。

    Use Showroom
    SELECT Name,Make,Model, Price, Type,
    RANK() OVER(ORDER BY Price DESC) as PriceRank
    FROM Car

    上記のスクリプトで、「PriceRank」列として、名前、メーカー、モデル、価格、タイプ、および価格順に注文された各車のランクを選択します。ランク関数の構文は単純です。関数RANKの後にOVER演算子を記述する必要があります。 OVER演算子内で、データをソートするORDERBY句を渡す必要があります。上記のスクリプトの出力は次のようになります:

    各車のランクを確認できます。 2つのレコードのランクが同点の場合、次のランクの位置はスキップされることに注意してください。たとえば、出力のレコード5と6の間には同点があります。パラドとシビックは同じ価格なので5位にランクされています。ただし、次のランク、特にランク6はスキップされ、リストの次の2台の車も同じ価格であるため7位にランク付けされています。 7番目のランクの後、ランク8は再びスキップされ、次に割り当てられるランクは9になります。

    データをパーティションに分割してから、個々のパーティションにランキングを適用できます。次のスクリプトでは、タイプごとのレコードのパーティションがあります。各パーティション内の車をランク付けします。

    SELECT Name,Make,Model, Price, Type,
    RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as PriceRank
    FROM Car

    上記のスクリプトの出力は次のようになります:

    出力から、レコードが車のタイプに従ってパーティション化されており、ランクがパーティション内でローカルに割り当てられていることがわかります。たとえば、最初の2つのレコードはパーティション「ハッチバック」に属し、1と2にランク付けされています。次のパーティション、つまり「セダン」では、ランクが1にリセットされます。

    2。 Dense_Rank関数

    density_rank関数はrank関数に似ています。ただし、density_rankの場合、ランクに関して2つのレコードが同点の場合、次のランクはスキップされません。例を使ってそれを示してみましょう。次のスクリプトを実行します。

    Use Showroom
    SELECT Name,Make,Model, Price, Type,
    DENSE_RANK() OVER(ORDER BY Price DESC) as DensePriceRank
    FROM Car

    ここでも、5番目と6番目のレコードのPriceの値が同じで、両方にランク5が割り当てられていることがわかります。ただし、次のランクをスキップしたランク関数とは異なり、dense_rank関数は次のランクとランク6をスキップしません。次のレコードに割り当てられました。

    ランク関数と同様に、dense_rank関数もpartitionby句に適用できます。次のスクリプトを見てください:

    SELECT Name,Make,Model, Price, Type,
    DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank
    FROM Car

    上記のスクリプトの出力は次のようになります:

    3。 Row_Number関数

    row_number関数は、ORDERBY句で指定された条件に従ってレコードもランク付けします。ただし、rank関数やdense_rank関数とは異なり、row_number関数は、ORDERBY句で指定された列に重複する値がある場合に同じランクを割り当てません。次のスクリプトを見てください:

    SELECT Name,Make,Model, Price, Type,
    DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank
    FROM Car

    上記のスクリプトの出力は次のようになります:

    上記のスクリプトから、5番目と6番目のレコードの両方のPrice列の値は同じですが、それらに割り当てられているランクが異なることがわかります。

    同様に、row_number関数はパーティション化されたデータに適用できます。たとえば、次のスクリプトを見てください。

    SELECT Name,Make,Model, Price, Type,
    ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Price DESC) AS PriceRankRow
    FROM Car

    上記のスクリプトの出力は次のようになります:

    4。 NTILE関数

    NTILE関数はランキングをグループ化します。テーブルに12個のレコードがあり、それらを4つのグループにランク付けするとします。最初の3つのレコードはランク1になり、次の3つのレコードはランク2になります。

    NTILE関数の例を見てみましょう。

    Use Showroom
    SELECT Name,Make,Model, Price, Type,
    NTILE(4) OVER(ORDER BY Price DESC) as NtilePrice
    FROM Car

    上記のスクリプトでは、NTILE関数にパラメーターとして4を渡しました。 12のレコードがあるため、合計4つの異なるランクが表示され、1つのランクが3つのレコードに割り当てられます。出力は次のようになります:

    最初の3台の最も高価な車が1位にランク付けされ、次の3台が2位にランク付けされていることがわかります。

    NTILE関数は、パーティション化されたデータにも適用できます。次のスクリプトを見てください:

    SELECT Name,Make,Model, Price, Type,
    NTILE(4) OVER(PARTITION BY Type ORDER BY Price DESC) as NtilePrice
    FROM Car

    結論

    SQL Serverのランク付け関数は、さまざまな方法でデータをランク付けするために使用されます。この記事では、例を使用してさまざまなタイプのランキング関数を紹介しました。 rank関数とdense_rank関数は、ORDER BY句で同じ値を持つデータに同じランクを与えますが、row_number関数は、同点の場合でもレコードを段階的にランク付けします。
    指定された列に重複するレコードがない場合ORDER BY句により、rank、dense_rank、row_number関数は同様に動作します。


    1. PostgreSQLデータベースサービス

    2. MySQLルートユーザーの完全な権限を復元するにはどうすればよいですか?

    3. ListViewコントロールのドラッグドロップソートイベント

    4. SQLコマンドの概要