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. 执行删除前一定要先查询预览
相关推荐
这个DBA有点耶6 分钟前
库内语义构建 vs 外挂向量库:业务语义缺失,才是RAG“胡说八道”的根源
数据库·mysql·aigc
kobe_OKOK_1 小时前
mysql 开启 binlog 日志
数据库·mysql
鸽芷咕2 小时前
KingbaseES 调参先看执行计划,参数是答案不是起点
数据库
这个DBA有点耶2 小时前
MySQL 8.0直方图:统计信息升级了,执行计划为什么还是选错?
数据库·mysql·代码规范
老纪的技术唠嗑局4 小时前
把 seekdb 塞进 iOS App:让混合检索嵌入手机
数据库
ClouGence5 小时前
开源数据库管理工具 CloudDM 新版本发布,支持 OpenSearch、IoTDB 数据源
数据库·开源
徐小黑ACG5 小时前
Redis-基础
数据库·redis·缓存
火山引擎开发者社区6 小时前
案例实践 | 让 Agent 读懂业务口径:ContextSearch 在广告数据查询中的实践
数据库
10年前端老司机7 小时前
Milvus 8种检索能力实践
数据库·python·agent
aiks_yuan7 小时前
MySQL 深分页 LIMIT 越翻越慢怎么办:300 万行实测 OFFSET、延迟关联和 keyset 的耗时差距(MySQL 8.2)
mysql