SQL 方言通

首页 / 窗口

ROW_NUMBER 分区内连续编号

ROW_NUMBER() 按 ORDER BY 给分区内每一行编号,从 1 开始连续递增,值相同也不会重复。七个引擎写法相同,常用于去重和分组取前 N 条。差异在能否用 QUALIFY 直接过滤,以及 Flink 流模式必须按固定写法使用。

各引擎写法 · 迁移注意事项 · 示例

各引擎写法

引擎支持写法说明依据
MaxCompute支持ROW_NUMBER() OVER ([partition_clause] [orderby_clause])返回 BIGINT。窗口定义里不允许写 frame 子句。支持用 QUALIFY 直接过滤窗口函数结果。官方文档
Hologres支持ROW_NUMBER() OVER (...)Hologres V1.1 起由 HQE 执行引擎支持,返回 BIGINT。官方文档
StarRocks支持ROW_NUMBER() OVER (partition_by_clause order_by_clause)编号不重复、不跳号。2.5 起支持 QUALIFY,QUALIFY 后只能跟 ROW_NUMBER、RANK 和 DENSE_RANK。官方文档
Doris支持ROW_NUMBER() OVER (...)返回 BIGINT,从 1 开始连续递增,分区内唯一。官方文档已实测 4.1.5
Hive支持ROW_NUMBER() OVER (...)属于 Hive 的窗口和分析函数。过滤编号需要套一层子查询。官方文档已实测 4.2.1
Spark SQL支持row_number() OVER (...)Spark 2.0.0 起提供,按窗口分区内的排序从 1 开始编号。官方文档
Flink SQL支持ROW_NUMBER() OVER ([PARTITION BY ...] ORDER BY ...)主要用于 Top-N 和去重查询,必须严格按文档写法,否则优化器无法识别。Top-N 结果会不断更新,写入外部存储时,结果表要有与查询相同的唯一键。官方文档已实测 2.3.0

迁移注意事项

示例

每个用户只保留最新一笔订单

MaxCompute
SELECT user_id, order_id, order_time FROM (SELECT user_id, order_id, order_time, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_time DESC, order_id DESC) AS rn FROM orders) t WHERE rn = 1;
Hologres
SELECT user_id, order_id, order_time FROM (SELECT user_id, order_id, order_time, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_time DESC, order_id DESC) AS rn FROM orders) t WHERE rn = 1;
StarRocks
SELECT user_id, order_id, order_time FROM (SELECT user_id, order_id, order_time, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_time DESC, order_id DESC) AS rn FROM orders) t WHERE rn = 1;
Doris
SELECT user_id, order_id, order_time FROM (SELECT user_id, order_id, order_time, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_time DESC, order_id DESC) AS rn FROM orders) t WHERE rn = 1;
Hive
SELECT user_id, order_id, order_time FROM (SELECT user_id, order_id, order_time, row_number() OVER (PARTITION BY user_id ORDER BY order_time DESC, order_id DESC) AS rn FROM orders) t WHERE rn = 1;
Spark SQL
SELECT user_id, order_id, order_time FROM (SELECT user_id, order_id, order_time, row_number() OVER (PARTITION BY user_id ORDER BY order_time DESC, order_id DESC) AS rn FROM orders) t WHERE rn = 1;
Flink SQL
SELECT user_id, order_id, order_time FROM (SELECT user_id, order_id, order_time, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_time DESC, order_id DESC) AS rn FROM orders) WHERE rn = 1;

同类函数

窗口:全部引擎写法对照

核对日期: · 提交勘误