Oracle数据库:按物料编号返回前两条记录的实现需求
Oracle按物料分组取前两条记录的实现方法
原表数据
Material QTY MONTH_YEAR 1 , 1 2020-07 1 , 2 2020-04 1 , 2 2020-03 1 , 2 2020-05 2 , 3 2020-10 2 , 4 ,2020-08 2 , 4 ,2020-08 3 , 4 ,2021-08 3 , 4 ,2021-08 3 , 4 ,2020-08 3 , 4 ,2020-08 3 , 4 ,2019-08
需求
为每个Material(物料编号)返回前两条记录。
实现方案
Oracle中最常用**窗口函数ROW_NUMBER()**实现分组取Top N的需求,具体SQL如下:
-- 替换your_table_name为你的实际表名 SELECT Material, QTY, MONTH_YEAR FROM ( SELECT Material, QTY, MONTH_YEAR, -- 按物料分组,每组内按年月倒序生成行号 ROW_NUMBER() OVER(PARTITION BY Material ORDER BY MONTH_YEAR DESC) AS row_num FROM your_table_name ) grouped_data WHERE row_num <= 2;
代码说明
PARTITION BY Material:将数据按物料编号拆分分组,每组独立计算行号ORDER BY MONTH_YEAR DESC:每组内按年月倒序排序(如需保留原始插入顺序,可改为ORDER BY ROWID;按数量排序则改为ORDER BY QTY DESC)- 外层查询过滤行号≤2的记录,得到每组前两条
特殊场景处理
如果需要保留同排名的重复记录(比如物料2的两条2020-08记录都要保留),可以用RANK()或DENSE_RANK()替换ROW_NUMBER():
SELECT Material, QTY, MONTH_YEAR FROM ( SELECT Material, QTY, MONTH_YEAR, RANK() OVER(PARTITION BY Material ORDER BY MONTH_YEAR DESC) AS rank_num FROM your_table_name ) grouped_data WHERE rank_num <= 2;
注:你提供的期望输出中物料3的第二条记录2021-0应为笔误,实际执行后会返回2021-08的记录。
内容的提问来源于stack exchange,提问作者Danvin Lee Qicheng
相关产品推荐
相关产品推荐

