更新时间:2022-09-29 GMT+08:00

Top-N

功能描述

Top-N 查询是根据列排序找到N个最大或最小的值。最大值集和最小值集都被视为是一种 Top-N 的查询。若在批处理或流处理的表中需要显示出满足条件的 N 个最底层记录或最顶层记录, Top-N 查询将会十分有用。

语法格式

SELECT [column_list]
FROM (
   SELECT [column_list],
     ROW_NUMBER() OVER ([PARTITION BY col1[, col2...]]
       ORDER BY col1 [asc|desc][, col2 [asc|desc]...]) AS rownum
   FROM table_name)
WHERE rownum <= N [AND conditions]

语法说明

  • ROW_NUMBER(): 根据当前分区内的各行的顺序从第一行开始,依次为每一行分配一个唯一且连续的号码。目前,我们只支持 ROW_NUMBER 在 over 窗口函数中使用。未来将会支持 RANK() 和 DENSE_RANK()函数。
  • PARTITION BY col1[, col2...]: 指定分区列,每个分区都将会有一个 Top-N 结果。
  • ORDER BY col1 [asc|desc][, col2 [asc|desc]...]: 指定排序列,不同列的排序方向可以不一样。
  • WHERE rownum <= N: Flink 需要 rownum <= N 才能识别一个查询是否为 Top-N 查询。 其中, N 代表最大或最小的 N 条记录会被保留。
  • [AND conditions]: 在 where 语句中,可以随意添加其他的查询条件,但其他条件只允许通过 AND 与 rownum <= N 结合使用。

注意事项

  • TopN 查询的结果会带有更新。
  • Flink SQL 会根据排序键对输入的流进行排序。
  • 如果 top N 的记录发生了变化,变化的部分会以撤销、更新记录的形式发送到下游。
  • 如果 top N 记录需要存储到外部存储,则结果表需要拥有相同与 Top-N 查询相同的唯一键。

示例

查询每个分类实时销量最大的五个产品

SELECT * 
  FROM ( 
     SELECT *,
         ROW_NUMBER() OVER (PARTITION BY category ORDER BY sales DESC) as row_num
     FROM ShopSales)
  WHERE row_num <= 5;