Oracle实现筛选过滤后分组内DMD_WK与WIP均为最小值的行
实现方案
方案1:使用窗口函数(推荐)
Oracle 支持的ROW_NUMBER()窗口函数可以直接实现分组排序取首行的需求,代码逻辑清晰,性能优异:
SELECT * FROM ( SELECT t.*, ROW_NUMBER() OVER ( PARTITION BY Item, Week, Qty ORDER BY DMD_WK ASC, WIP ASC ) AS rn FROM 你的原始表名 t -- 第一步过滤条件 WHERE Qty < ACC_DMD ) WHERE rn = 1;
逻辑说明:
PARTITION BY Item, Week, Qty按照要求的维度分组,每个分组内独立计算排序序号ORDER BY DMD_WK ASC, WIP ASC分组内先按需求排最小的DMD_WK,同DMD_WK下排最小的WIP,符合要求的行序号为1- 外层过滤取
rn=1的行即为最终结果
如果你第一步过滤后的结果已经存储在临时表temp_filtered中,直接替换内层FROM后的表名即可。
如果存在多条行同时满足最小DMD_WK和最小WIP、需要全部取出的场景,把ROW_NUMBER()替换为RANK()即可。
方案2:使用KEEP聚合函数(Oracle特有)
如果你习惯用分组聚合的写法,可以用Oracle特有的KEEP函数实现:
SELECT t1.* FROM 你的原始表名 t1 INNER JOIN ( SELECT Item, Week, Qty, MIN(DMD_WK) AS min_dmd_wk, MIN(WIP) KEEP (DENSE_RANK FIRST ORDER BY DMD_WK) AS min_wip FROM 你的原始表名 WHERE Qty < ACC_DMD GROUP BY Item, Week, Qty ) t2 ON t1.Item = t2.Item AND t1.Week = t2.Week AND t1.Qty = t2.Qty AND t1.DMD_WK = t2.min_dmd_wk AND t1.WIP = t2.min_wip;
KEEP (DENSE_RANK FIRST ORDER BY DMD_WK)的作用是取分组内DMD_WK最小的那些行,再取这些行里的最小WIP,和需求完全匹配。
内容的提问来源于stack exchange,提问作者Vinz Sumampong
相关产品推荐
相关产品推荐

