MySQL 重复数据删除语句

方案 1:有自增主键 id(推荐,最安全)

假设你的表有主键:id(没有就用方案 2)

复制代码
DELETE a
FROM leave_sdxw a
JOIN (
    -- 找出每组重复数据中 最小的id之外的所有记录
    SELECT tenant_id, sddm, fill_vpdm, MIN(id) AS keep_id
    FROM leave_sdxw
    WHERE fill_vpdm IS NOT NULL
    GROUP BY tenant_id, sddm, fill_vpdm
    HAVING COUNT(*) > 1
) b ON a.tenant_id = b.tenant_id 
   AND a.sddm = b.sddm 
   AND a.fill_vpdm = b.fill_vpdm 
   AND a.id > b.keep_id; -- 只删大于最小id的重复数据

方案 2:没有主键 / 唯一列(不推荐,但能用)

复制代码
-- 先创建临时表存储重复组合
CREATE TEMPORARY TABLE tmp_repeat AS
SELECT tenant_id, sddm, fill_vpdm
FROM leave_sdxw
WHERE fill_vpdm IS NOT NULL
GROUP BY tenant_id, sddm, fill_vpdm
HAVING COUNT(*) > 1;

-- 删除重复(会每组只留一条,取决于数据库存储顺序)
DELETE a
FROM leave_sdxw a
JOIN tmp_repeat b 
ON a.tenant_id = b.tenant_id 
AND a.sddm = b.sddm 
AND a.fill_vpdm = b.fill_vpdm;

-- 删除临时表
DROP TEMPORARY TABLE IF EXISTS tmp_repeat;

执行前建议 先执行查询确认要删的数据,不要直接删

复制代码
-- 先查询,确认重复数据
SELECT a.*
FROM leave_sdxw a
JOIN (
    SELECT tenant_id, sddm, fill_vpdm, MIN(id) AS keep_id
    FROM leave_sdxw
    WHERE fill_vpdm IS NOT NULL
    GROUP BY tenant_id, sddm, fill_vpdm
    HAVING COUNT(*) > 1
) b ON a.tenant_id = b.tenant_id 
   AND a.sddm = b.sddm 
   AND a.fill_vpdm = b.fill_vpdm 
   AND a.id > b.keep_id;

总结

  1. 优先用方案 1(带主键 id),安全、高效、不会删光数据
  2. 执行删除前一定要先查询预览
相关推荐
ego.iblacat2 小时前
PostgreSQL 数据库
数据库·postgresql
wgzrmlrm742 小时前
如何解决ORA-28040没有匹配的验证协议_sqlnet.ora版本兼容设置
jvm·数据库·python
一江寒逸2 小时前
零基础从入门到精通MySQL(附加篇):面试八股文全集
数据库·mysql·面试
数厘3 小时前
2.6MySQL库表操作指南(电商数据分析专用)
数据库·mysql·数据分析
需要点灵感3 小时前
SQL Server 存储过程语法整理
数据库·sql
刘~浪地球3 小时前
数据库与缓存--分库分表实战指南
网络·数据库·缓存
Mr_Xuhhh3 小时前
深入Java多线程进阶:从锁策略到并发工具全解析
前端·数据库·python
数厘3 小时前
2.5可视化工具与 MySQL 连接配置及基础操作
数据库·mysql
沃尔威武3 小时前
性能调优实战:从火焰图定位到SQL优化的全流程
android·数据库·sql