DENSE_RANK 関数は、RANK 関数と同様に、その他のローの値と比較した現在のローの値のランクを返します。値のランクは、値のリストがソートされた場合の順序を反映しています。ランクは、ウィンドウの ORDER BY 句で指定された式で計算されます。
DENSE_RANK 関数は、ランク値にギャップ (ジャンプ) がなく単調に増加し続ける一連のランクを返します。RANK 値とは異なり、ランク値にジャンプがないことから DENSE (密) という語が使われます。
ウィンドウが入力ローを移動するのに合わせて、ウィンドウの ORDER BY 句で指定された式でランクが計算されます。ORDER BY 句に複数の式が含まれる場合は、最初の式によって隣接ローで同じ値になるときに同順の発生を避けるために、2 番目以降の式が使用されます。NULL 値はその他の値よりも前にソートされます (昇順の場合)。
次のクエリは、データベースで最もコストが高い製品 3 つを特定します。ウィンドウでは降順のソート順序が指定されるため、最もコストの高い製品はランクが最も低くなります。つまり、ランク付けは 1 から開始します。
SELECT Top 3 * FROM ( SELECT Description, Quantity, UnitPrice, DENSE_RANK( ) OVER ( ORDER BY UnitPrice DESC ) AS Rank FROM Products ) AS DT ORDER BY Rank; |
このクエリは、次の結果を返します。
Description | Quantity | UnitPrice | Rank | |
---|---|---|---|---|
1 | Hooded Sweatshirt | 39 | 24.00 | 1 |
2 | Zipped Sweatshirt | 32 | 24.00 | 1 |
3 | Cotton Shorts | 80 | 15.00 | 2 |
ロー 1 と 2 は、UnitPrice の値が同じであるため、ランクも同じになります。これを「同順」と呼びます。
DENSE_RANK 関数を使用した場合は、同順の後のランク値はジャンプしません。たとえば、ロー 3 のランク値は 2 です。この動作は、同順の後でランク値がジャンプする RANK 関数と異なります。
ウィンドウはクエリの GROUP BY 句の後に評価されるため、集合関数の値を基にランキングを判断するような複雑な要求を指定できます。
次のクエリは、地域ごとに総売り上げ上位 3 人の営業担当者と、地域ごとの総売り上げを生成します。
SELECT * FROM ( SELECT o.SalesRepresentative, o.Region, SUM( s.Quantity * p.UnitPrice ) AS total_sales, DENSE_RANK( ) OVER ( PARTITION BY o.Region, GROUPING( o.SalesRepresentative ) ORDER BY total_sales DESC ) AS sales_rank FROM Products p, SalesOrderItems s, SalesOrders o WHERE p.ID = s.ProductID AND s.ID = o.ID GROUP BY GROUPING SETS( ( o.SalesRepresentative, o.Region ), o.Region ) ) AS DT WHERE sales_rank <= 3 ORDER BY Region, sales_rank; |
このクエリは、次の結果を返します。
SalesRepresentative | Region | total_sales | sales_rank | |
---|---|---|---|---|
1 | 299 | Canada | 9312.00 | 1 |
2 | (NULL) | Canada | 24768.00 | 1 |
3 | 1596 | Canada | 3564.00 | 2 |
4 | 856 | Canada | 2724.00 | 3 |
5 | 299 | Central | 32592.00 | 1 |
6 | (NULL) | Central | 134568.00 | 1 |
7 | 856 | Central | 14652.00 | 2 |
8 | 467 | Central | 14352.00 | 3 |
9 | 299 | Eastern | 21678.00 | 1 |
10 | (NULL) | Eastern | 142038.00 | 1 |
11 | 902 | Eastern | 15096.00 | 2 |
12 | 690 | Eastern | 14808.00 | 3 |
13 | 1142 | South | 6912.00 | 1 |
14 | (NULL) | South | 45262.00 | 1 |
15 | 667 | South | 6480.00 | 2 |
16 | 949 | South | 5782.00 | 3 |
17 | 299 | Western | 5640.00 | 1 |
18 | (NULL) | Western | 37632.00 | 1 |
19 | 1596 | Western | 5076.00 | 2 |
20 | 667 | Western | 4068.00 | 3 |
このクエリは、GROUPING SETS を使用して複数のグループ化を結合します。そのため、ウィンドウの WINDOW PARTITION 句では GROUPING 関数を使用して、特定の営業担当者を表すディテールローと、地域全体の総売り上げをリストする小計ローとを区別します。地域ごとの小計のローは、SalesRepresentative 属性に値 NULL がありますが、入力の分割ごとに結果のランキング順序が付けられるため、それぞれの小計ローのランキング値は 1 になります。これにより、ディテールローは 1 から適切にランク付けされます。
この例では、DENSE_RANK 関数により、総売り上げの集約について入力がランク付けされています。WINDOW ORDER 句では、エイリアスの設定された SELECT リスト項目が省略形として使用されます。
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |