SQL Server中基于多列删除重复行(保留最新日期行)
针对你要删除DATA_ID和SourceID组合重复的行、仅保留DateAdded最新行的需求,我先把你提供的数据整理成清晰的表格:
| id | DATA_ID | SourceID | DateAdded |
|---|---|---|---|
| 1 | 304019032 | 1 | 2018-01-20 |
| 2 | 345583556 | 1 | 2018-01-21 |
| 3 | 299951717 | 3 | 2018-01-23 |
| 4 | 304019032 | 2 | 2018-01-24 |
| 5 | 298519282 | 2 | 2018-01-24 |
| 6 | 299951717 | 3 | 2018-01-27 |
| 7 | 345583556 | 1 | 2018-01-27 |
下面给你几个实用的SQL解决方案,适配不同的数据库环境:
方法一:窗口函数(推荐,支持MySQL 8+、PostgreSQL、SQL Server等现代数据库)
这种方法逻辑清晰,容易理解,也能处理复杂的分组场景:
-- 第一步:先查询确认要保留的行,确保结果符合预期 SELECT * FROM ( SELECT *, -- 按DATA_ID+SourceID分组,按DateAdded倒序编号,最新的行编号为1 ROW_NUMBER() OVER (PARTITION BY DATA_ID, SourceID ORDER BY DateAdded DESC) AS row_num FROM your_table_name ) grouped_data WHERE row_num = 1; -- 第二步:确认无误后执行删除操作 DELETE FROM your_table_name WHERE id NOT IN ( SELECT id FROM ( SELECT id, ROW_NUMBER() OVER (PARTITION BY DATA_ID, SourceID ORDER BY DateAdded DESC) AS row_num FROM your_table_name ) grouped_data WHERE row_num = 1 );
方法二:DELETE JOIN(适合MySQL 5.x等不支持窗口函数的旧版本)
如果你的数据库版本比较旧,用关联删除的方式也能实现需求:
-- 删除所有同分组下日期更早的行 DELETE t1 FROM your_table_name t1 INNER JOIN your_table_name t2 ON t1.DATA_ID = t2.DATA_ID AND t1.SourceID = t2.SourceID AND t1.DateAdded < t2.DateAdded;
⚠️ 注意:如果存在同一分组内有多行DateAdded完全相同的情况,这个方法会保留所有这些行。如果需要只留其中一行,可以在JOIN条件里再加个AND t1.id < t2.id,确保只保留id更大的那一行。
重要提示
- 执行删除操作前,一定要先备份数据,或者先运行SELECT语句验证要保留/删除的行是否正确,避免误操作。
- 把代码里的
your_table_name替换成你实际使用的表名。
内容的提问来源于stack exchange,提问作者infosec




