与 RANK 函数类似,当与其它行中的值进行比较时,使用 DENSE_RANK 函数返回当前行中值的秩。值的秩反映值在已排序的值列表中出现的位置。将为在窗口的 ORDER BY 子句中所指定的表达式计算秩。
DENSE_RANK 函数将返回一系列的秩,这些秩值将单调递增而不会有空位或跳跃。因为在秩值中没有跳跃(与 RANK 函数不同),所以使用了术语紧凑 (dense)。
随着窗口在输入行中向下移动,会计算在窗口的 ORDER BY 子句中所指定的表达式的秩。当 ORDER BY 子句包括多个表达式时,若第一个表达式与相邻行具有相同值,则第二个及后续表达式将用于区分并列情况。NULL 值排在任何其它值的前面(在升序序列中)。
以下查询确定数据库中三种最贵的产品。由于在窗口中指定了降序排序,因此最贵产品的秩最低(秩从 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 行中的 Unit Price 值相同,因此具有相同的秩。这称为并列。
使用 DENSE_RANK 函数时,在出现并列之后不发生跳跃。例如,第 3 行的秩值是 2。这一点与 RANK 函数不同,RANK 函数在出现并列之后秩值会发生跳跃。
因为执行查询的 GROUP BY 子句之后会对窗口进行求值,所以您可以指定根据集合函数的值确定秩的复杂请求。
以下查询根据销售人员在其地区的总销售额,查询出各地区的前三名销售人员以及各地区的总销售额:
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 函数来区分详细信息行和小计行,其中详细信息行表示特定销售人员,而小计行列出整个地区的总销售额。按地区的小计行中,销售代表属性的值为 NULL,而每行的秩值均为 1,这是由于结果的秩排序在输入的每个分区中都重新开始;这样就确保了详细信息行都能从 1 开始正确排序。
最后要注意的是,在此示例中 DENSE_RANK 函数对输入的排序优先于总销售额集合。带别名的 SELECT 列表项在 WINDOW ORDER 子句中用作速记。
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2013, SAP 股份公司或其关联公司. - SAP Sybase SQL Anywhere 16.0 |