SQL中如何从重复行筛选指定值?求正确实现方案
问题分析与解决方案
你的原SQL语句意图是获取每个(MANDT, ID)分组中DATE最大的记录,但执行结果不符合预期,大概率是因为同一个分组内存在多条DATE相同且为最大值的记录——此时原SQL会返回所有这些记录,无法满足你“单条目标记录”的需求。
要实现每组仅返回一条记录的目标,可以根据你的具体需求(比如当DATE相同时如何筛选)选择以下方案:
方案1:使用窗口函数(推荐,直观易维护)
利用ROW_NUMBER()窗口函数为每个分组内的记录排序,取排序后的第一条:
SELECT MANDT, ID, DATE, CODE FROM ( SELECT *, -- 按MANDT、ID分组,先按DATE降序(取最新日期),DATE相同时按CODE降序(取CODE最大的,可按需调整) ROW_NUMBER() OVER (PARTITION BY MANDT, ID ORDER BY DATE DESC, CODE DESC) AS row_num FROM Table_a ) AS temp WHERE row_num = 1;
PARTITION BY MANDT, ID:将数据按这两个字段分组ORDER BY DATE DESC, CODE DESC:分组内先按DATE从大到小排序,DATE相同时按CODE从大到小排序(你可以根据实际需求修改排序规则,比如改成CODE ASC取最小的CODE)row_num = 1:只保留每组排序后的第一条记录,确保每组仅返回一条
方案2:调整原NOT EXISTS语句
如果坚持使用NOT EXISTS,可以在条件中补充DATE相同时的筛选逻辑,确保每组仅返回一条:
SELECT a.* FROM Table_a a WHERE NOT EXISTS ( SELECT 1 FROM Table_a b WHERE a.MANDT = b.MANDT AND a.ID = b.ID -- 筛选出比当前记录DATE更大,或DATE相同但CODE更大的记录 AND (a.DATE < b.DATE OR (a.DATE = b.DATE AND a.CODE < b.CODE)) )
这个语句会返回每个分组中DATE最大,且DATE相同时CODE最大的记录,保证每组仅一条。
方案3:聚合函数+JOIN(适合不支持窗口函数的旧版数据库)
如果你的数据库不支持窗口函数,可以先聚合出每组的最大DATE,再关联原表,若仍有重复则进一步聚合:
-- 第一步:获取每组的最大DATE WITH max_date_cte AS ( SELECT MANDT, ID, MAX(DATE) AS max_date FROM Table_a GROUP BY MANDT, ID ) -- 第二步:关联原表,若DATE相同的记录仍有多个,用MAX(CODE)取唯一值 SELECT a.MANDT, a.ID, m.max_date, MAX(a.CODE) AS CODE FROM Table_a a JOIN max_date_cte m ON a.MANDT = m.MANDT AND a.ID = m.ID AND a.DATE = m.max_date GROUP BY a.MANDT, a.ID, m.max_date;
内容的提问来源于stack exchange,提问作者Ichichaa
相关产品推荐
相关产品推荐

