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. 执行删除前一定要先查询预览
相关推荐
GBASE12 小时前
G术时刻 |GBase 8s数据库事务并发控制之封锁技术介绍(下)
数据库
xiezhr1 天前
逛GitHub发现了一款免费的带AI功能的数据库管理工具
数据库·ai编程·dba
唐青枫2 天前
MySQL JSON 实战详解:从存储、查询、更新到 JSON_TABLE 与索引
sql·mysql
吃糖的小孩2 天前
给 QQ AI 机器人设计“可控记忆”:会话摘要、手动长期记忆与角色卡边界
数据库
小满8782 天前
5.Mysql事务隔离级别与锁机制
mysql
笃行3503 天前
金仓数据库数据安全双防线:静态存储加密与传输加密实战
数据库
笃行3503 天前
金仓数据库物理备份实战:sys_rman 全流程演练与误覆盖抢救
数据库
笃行3503 天前
金仓数据库逻辑备份实战:从全库导出到 Schema 替换的完整闭环
数据库
元Y亨H3 天前
技术笔记:MySQL 字符集排序规则与大小写敏感性问题解决方案
mysql