Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 的用法 » 查询和修改数据 » OLAP 支持 » SQL Anywhere 中的窗口函数 » 窗口秩函数

 

DENSE_RANK 函数

与 RANK 函数类似,当与其它行中的值进行比较时,使用 DENSE_RANK 函数返回当前行中值的秩。值的秩反映值在已排序的值列表中出现的位置。将为在窗口的 ORDER BY 子句中所指定的表达式计算秩。

DENSE_RANK 函数将返回一系列的秩,这些秩值将单调递增而不会有空位或跳跃。因为在秩值中没有跳跃(与 RANK 函数不同),所以使用了术语紧凑 (dense)。

随着窗口在输入行中向下移动,会计算在窗口的 ORDER BY 子句中所指定的表达式的秩。当 ORDER BY 子句包括多个表达式时,若第一个表达式与相邻行具有相同值,则第二个及后续表达式将用于区分并列情况。NULL 值排在任何其它值的前面(在升序序列中)。

示例 1

以下查询确定数据库中三种最贵的产品。由于在窗口中指定了降序排序,因此最贵产品的秩最低(秩从 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 函数在出现并列之后秩值会发生跳跃。请参见RANK 函数

示例 2

因为执行查询的 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 函数对输入的排序优先于总销售额集合。带别名的选择列表项在 WINDOW ORDER 子句中用作速记。

有关 DENSE_RANK 函数语法的详细信息,请参见DENSE_RANK 函数 [Ranking]