如何在Snowflake中获取row_number()窗口函数结果的最后两行
Snowflake中提取窗口函数结果最后2行的实现方案
以下是三种可直接落地的实现方式,按性能从高到低排序:
- 反向排序取前2行(性能最优)
不需要二次聚合计算最大行号,只需要把原row_number()的排序规则反转,筛选反向排名前2的记录即可。如果原窗口带PARTITION BY分区逻辑,反向排序的分区字段必须和原逻辑完全一致。
示例代码:-- 原逻辑是按col1、col2升序打正向行号 WITH base_data AS ( SELECT *, -- 排序规则和原逻辑完全反向,分区字段保持不变 ROW_NUMBER() OVER (PARTITION BY 分区字段 ORDER BY col1 DESC, col2 DESC) AS reverse_rn FROM 你的业务表 -- 此处可叠加原有业务过滤条件 ) SELECT * FROM base_data WHERE reverse_rn <= 2; - 同窗口计算总行数筛选(保留正向行号场景用)
如果业务需要保留原正向生成的行号,不需要改动排序逻辑,可以在同窗口下用COUNT()计算当前分区的总行数,直接筛选行号为倒数2位的记录即可。
示例代码:WITH base_data AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY 分区字段 ORDER BY col1, col2) AS rn, -- 窗口定义和row_number完全一致,计算当前分区总记录数 COUNT(*) OVER (PARTITION BY 分区字段 ORDER BY col1, col2 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS total_rows FROM 你的业务表 ) SELECT * FROM base_data WHERE total_rows - rn < 2; - 聚合最大行号关联匹配(逻辑最直观)
先通过子查询计算每个分区下的最大行号,再关联回原结果集匹配最后2行的行号,写法容易理解,适合小数据量场景使用。
示例代码:WITH base_data AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY 分区字段 ORDER BY col1, col2) AS rn FROM 你的业务表 ), partition_max_rn AS ( SELECT 分区字段, MAX(rn) AS max_rn FROM base_data GROUP BY 分区字段 ) SELECT a.* FROM base_data a INNER JOIN partition_max_rn b ON a.分区字段 = b.分区字段 WHERE a.rn IN (b.max_rn, b.max_rn - 1);
通用提示:如果你的窗口没有设置分区(即全表排序打行号),上述代码里的
PARTITION BY 分区字段直接删除即可;如果需要提取最后N行,只需要把判断条件里的2替换为对应数值即可,比如取最后3行就把判断阈值改为3。
内容的提问来源于stack exchange,提问作者JVA
相关产品推荐
相关产品推荐

