DENSE_RANK 窗口函数 - Amazon Redshift

DENSE_RANK 窗口函数

DENSE_RANK 窗口函数基于 OVER 子句中的 ORDER BY 表达式确定一组值中的一个值的排名。如果存在可选的 PARTITION BY 子句,则为每个行组重置排名。带符合排名标准的相同值的行接收相同的排名。DENSE_RANK 函数与 RANK 存在以下一点不同:如果两个或两个以上的行结合,则一系列排名的值之间没有间隔。例如,如果两个行的排名为 1,则下一个排名则为 2

您可以在同一查询中包含带有不同的 PARTITION BY 和 ORDER BY 子句的排名函数。

语法

DENSE_RANK() OVER ( [ PARTITION BY expr_list ] [ ORDER BY order_list ] )

参数

( )

该函数没有参数,但需要空括号。

OVER

适用于 DENSE_RANK 函数的窗口子句。

PARTITION BY expr_list

(可选)一个或多个用于定义窗口的表达式。

ORDER BY order_list

(可选)排名值基于的表达式。如果未指定 PARTITION BY,则 ORDER BY 使用整个表。如果省略 ORDER BY,则所有行的返回值为 1

如果 ORDER BY 未生成唯一顺序,则行的顺序是不确定的。有关更多信息,请参阅 窗口函数的唯一数据排序

返回类型

INTEGER

示例

以下示例使用窗口函数的示例表。有关更多信息,请参阅 窗口函数示例的示例表

以下示例按销量对表进行排序,并将紧密排名和常规排名分配给每个行。在应用窗口函数结果后,对结果进行排序。

SELECT salesid, qty, DENSE_RANK() OVER(ORDER BY qty DESC) AS d_rnk, RANK() OVER(ORDER BY qty DESC) AS rnk FROM winsales ORDER BY 2,1; +---------+-----+-------+-----+ | salesid | qty | d_rnk | rnk | +---------+-----+-------+-----+ | 10001 | 10 | 5 | 8 | | 10006 | 10 | 5 | 8 | | 30001 | 10 | 5 | 8 | | 40005 | 10 | 5 | 8 | | 30003 | 15 | 4 | 7 | | 20001 | 20 | 3 | 4 | | 20002 | 20 | 3 | 4 | | 30004 | 20 | 3 | 4 | | 10005 | 30 | 2 | 2 | | 30007 | 30 | 2 | 2 | | 40001 | 40 | 1 | 1 | +---------+-----+-------+-----+

在同一查询中一起使用 DENSE_RANK 和 RANK 函数时,记下已分配给同一组行的排名的差异。

以下示例按 sellerid 对表进行分区,按数量对每个分区进行排序,并为每个行分配紧密排名。在应用窗口函数结果后,对结果进行排序。

SELECT salesid, sellerid, qty, DENSE_RANK() OVER(PARTITION BY sellerid ORDER BY qty DESC) AS d_rnk FROM winsales ORDER BY 2,3,1; +---------+----------+-----+-------+ | salesid | sellerid | qty | d_rnk | +---------+----------+-----+-------+ | 10001 | 1 | 10 | 2 | | 10006 | 1 | 10 | 2 | | 10005 | 1 | 30 | 1 | | 20001 | 2 | 20 | 1 | | 20002 | 2 | 20 | 1 | | 30001 | 3 | 10 | 4 | | 30003 | 3 | 15 | 3 | | 30004 | 3 | 20 | 2 | | 30007 | 3 | 30 | 1 | | 40005 | 4 | 10 | 2 | | 40001 | 4 | 40 | 1 | +---------+----------+-----+-------+

要成功使用上一个示例,请使用以下命令在 WINSALES 表中插入一行。该行与另一行具有相同的 buyerid、sellerid 和 qtysold。这将导致上一个示例中的两行并列,从而显示 DENSE_RANK 和 RANK 函数之间的差异。

INSERT INTO winsales VALUES(30009, '2/2/2003', 3, 'b', 20, NULL);

以下示例按 buyerid 和 sellerid 对表进行分区,按数量对每个分区进行排序,并为每个行分配紧密排名和常规排名。在应用窗口函数后,对结果进行排序。

SELECT salesid, sellerid, qty, buyerid, DENSE_RANK() OVER(PARTITION BY buyerid, sellerid ORDER BY qty DESC) AS d_rnk, RANK() OVER (PARTITION BY buyerid, sellerid ORDER BY qty DESC) AS rnk FROM winsales ORDER BY rnk; +---------+----------+-----+---------+-------+-----+ | salesid | sellerid | qty | buyerid | d_rnk | rnk | +---------+----------+-----+---------+-------+-----+ | 20001 | 2 | 20 | b | 1 | 1 | | 30007 | 3 | 30 | c | 1 | 1 | | 10006 | 1 | 10 | c | 1 | 1 | | 10005 | 1 | 30 | a | 1 | 1 | | 20002 | 2 | 20 | c | 1 | 1 | | 30009 | 3 | 20 | b | 1 | 1 | | 40001 | 4 | 40 | a | 1 | 1 | | 30004 | 3 | 20 | b | 1 | 1 | | 10001 | 1 | 10 | c | 1 | 1 | | 40005 | 4 | 10 | a | 2 | 2 | | 30003 | 3 | 15 | b | 2 | 3 | | 30001 | 3 | 10 | b | 3 | 4 | +---------+----------+-----+---------+-------+-----+