按Schemecode分组删除Fincode重复且Invdate更早的表数据
SQL解决方案:按分组删除重复的较早日期记录
嘿,我明白你要解决的问题了——按Schemecode分组,清理掉每组里同一Fincode下日期更早(2019-03-31)的重复记录,只保留2019-04-30的那条。这里有几种实用的SQL方案,适配不同的数据库环境:
方法一:窗口函数法(推荐给支持窗口函数的数据库)
如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server、Oracle等),这个方法逻辑清晰且高效:
WITH ranked_records AS ( SELECT Schemecode, Fincode, Invdate, -- 按Schemecode+Fincode分组,日期倒序排名,最新日期排第1 ROW_NUMBER() OVER ( PARTITION BY Schemecode, Fincode ORDER BY Invdate DESC ) AS rn FROM your_table_name -- 替换成你的实际表名 ) DELETE FROM your_table_name WHERE (Schemecode, Fincode, Invdate) IN ( SELECT Schemecode, Fincode, Invdate FROM ranked_records WHERE rn > 1 -- 删除排名大于1的(即较早的重复记录) );
逻辑说明:
- 用CTE给每个
Schemecode+Fincode组合的记录按日期降序排名,最新的2019-04-30会得到rn=1,较早的2019-03-31会得到rn>1。 - 直接删除所有
rn>1的记录,就能保留每组内最新的那条数据。
方法二:关联删除法(适配MySQL 5.x等旧版本)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以用关联查询来定位需要删除的记录:
DELETE t1 FROM your_table_name t1 JOIN your_table_name t2 ON t1.Schemecode = t2.Schemecode AND t1.Fincode = t2.Fincode AND t1.Invdate < t2.Invdate; -- 找到存在同组同Fincode且日期更晚的记录
逻辑说明:
这个查询会匹配出所有“存在同Schemecode+Fincode且日期更晚的记录”的行,然后直接删除这些较早的行,刚好符合你的需求。
方法三:临时表重建法(适合小数据量场景)
如果数据量不大,也可以先提取需要保留的记录,再重建表,逻辑更直观:
-- 1. 创建临时表,存储每个Schemecode+Fincode的最新日期记录 CREATE TABLE temp_table AS SELECT Schemecode, Fincode, MAX(Invdate) AS Invdate FROM your_table_name GROUP BY Schemecode, Fincode; -- 2. 清空原表数据 TRUNCATE TABLE your_table_name; -- 3. 将临时表的有效数据导回原表 INSERT INTO your_table_name (Schemecode, Fincode, Invdate) SELECT Schemecode, Fincode, Invdate FROM temp_table; -- 4. 清理临时表(可选) DROP TABLE temp_table;
逻辑说明:
通过GROUP BY直接获取每个Schemecode+Fincode组合的最大日期(也就是你要保留的2019-04-30),然后用这些数据替换原表内容,简单粗暴易理解。
执行完任意一种方法后,你可以用下面的查询验证结果:
SELECT * FROM your_table_name ORDER BY Schemecode, Fincode;
得到的结果会和你预期的完全一致。
内容的提问来源于stack exchange,提问作者shashikant kuswaha
相关产品推荐
相关产品推荐

