如何基于DATETIME列日期部分与另一列删除数据表重复行?
基于日期部分和指定列去重的解决方案
针对你要基于column1的日期部分(忽略时分秒)与column2组合去重、保留每组中一行的需求,之前提到的ALTER IGNORE方案在MySQL 5.7及以上版本已经被移除,所以这里给你几个可行的替代方案:
方案1:使用窗口函数(MySQL 8.0+ 推荐)
如果你的MySQL版本是8.0或更高,用ROW_NUMBER()窗口函数可以清晰地标记重复行,再删除多余的:
WITH ranked_rows AS ( SELECT column1, column2, -- 按日期部分+column2分组,每组内按column1升序排序(保留最早的记录) ROW_NUMBER() OVER ( PARTITION BY DATE(column1), column2 ORDER BY column1 ASC ) AS row_num FROM your_table ) DELETE FROM your_table WHERE (column1, column2) IN ( SELECT column1, column2 FROM ranked_rows WHERE row_num > 1 );
- 解释:
PARTITION BY DATE(column1), column2会把相同日期(仅日期部分)、相同column2值的行归为一组;ROW_NUMBER()给每组内的行编号,编号大于1的就是需要删除的重复行。如果想保留每组中最晚的记录,把ORDER BY column1 ASC改成DESC即可。
方案2:自连接删除(兼容MySQL 5.x版本)
对于低版本MySQL,可通过自连接找到重复行并删除:
DELETE t1 FROM your_table t1 JOIN your_table t2 ON DATE(t1.column1) = DATE(t2.column1) AND t1.column2 = t2.column2 AND t1.column1 > t2.column1; -- 保留较早的记录,要保留晚的就改成 t1.column1 < t2.column1
- 解释:通过自连接匹配同一日期、同一用户的行,删除比另一行时间晚的记录,最终每组只保留一条最早的记录。
方案3:临时表中转法(通用所有版本)
如果担心删除操作出错,可以先把去重后的结果存到临时表,再导回原表:
-- 1. 创建临时表,插入去重后的数据(保留每组最早的记录) CREATE TEMPORARY TABLE temp_table AS SELECT column1, column2 FROM your_table GROUP BY DATE(column1), column2 HAVING column1 = MIN(column1); -- 换成MAX(column1)可保留每组最晚的记录 -- 2. 清空原表(注意:此操作会删除所有数据,确保备份或确认需求) TRUNCATE TABLE your_table; -- 3. 将临时表的数据导回原表 INSERT INTO your_table (column1, column2) SELECT column1, column2 FROM temp_table; -- 4. 可选:删除临时表 DROP TEMPORARY TABLE temp_table;
验证结果
执行完上述任一方案后,查询原表:
SELECT * FROM your_table;
会得到你期望的结果:
column1 | column2 -----------------------|-------- 2020-01-01 11:11:11 | john 2020-07-07 17:17:11 | mike
内容的提问来源于stack exchange,提问作者Seeker
相关产品推荐
相关产品推荐

