最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何在SQL中快速找到并删除表中的重复记录?
时间:2026-07-12 09:50:52 编辑:袖梨 来源:一聚教程网
GROUP BY + HAVING 可精准识别按指定字段判定的重复值,如 SELECT email, COUNT() FROM users GROUP BY email HAVING COUNT() > 1;但不可直接删除,需配合子查询、窗口函数或临时表保留最小/最大id行,并务必先备份、验证再执行,最后添加唯一索引从源头防控。
用 GROUP BY + HAVING 找出重复主键字段
直接查重复行,关键不是看整行是否一样,而是明确你按哪些字段判定“重复”。比如用户表中 email 不该重复,那就只对 email 分组;如果业务要求 name 和 phone 组合唯一,就得写 GROUP BY name, phone。
常见错误是写 SELECT * 配合 GROUP BY —— 大多数数据库(如 MySQL 严格模式、PostgreSQL)会报错,因为非分组字段值不明确。正确做法是先聚焦识别逻辑:
SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;
这条语句能快速暴露哪些 email 出现了多次,且返回每组的出现次数,方便评估影响范围。
安全删除重复行:保留最小/最大 id 的那一行
删之前必须决定留哪一条——通常留 id 最小的(最早插入),或最大的(最新更新)。别用 DELETE FROM table WHERE ... 直接套子查询删全部,容易误删或锁表太久。
推荐用自连接或窗口函数(取决于数据库版本):
- MySQL 5.7+ / PostgreSQL / SQL Server:用
ROW_NUMBER()窗口函数标记重复组内的顺序 - SQLite 或老版本 MySQL:用自连接找“更大 id”的重复行,再删它们
例如在支持窗口函数的库中,删掉每个重复 email 中除最小 id 外的所有行:
DELETE FROM users WHERE id IN ( SELECT id FROM ( SELECT id, ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) AS rn FROM users ) t WHERE t.rn > 1);
注意:PARTITION BY email 定义重复组,ORDER BY id 决定谁被保留。改用 ORDER BY id DESC 就保留最新那条。
执行前务必备份或用事务包裹
删除操作不可逆,尤其当表大、索引缺失、或 WHERE 条件写错时,可能删掉全部数据。线上环境严禁跳过验证步骤。
实操建议:
- 先用
SELECT把将被删的id全部查出来,人工抽检几条确认逻辑 - 在事务里执行:
BEGIN; DELETE ...; SELECT COUNT(*) FROM users WHERE id IN (...); ROLLBACK;(测试完再COMMIT) - 避免在高峰期跑大表去重,
DELETE可能触发大量索引更新和锁等待
有些数据库(如 MySQL InnoDB)对大事务有 innodb_log_file_size 限制,删几十万行以上建议分批,比如每次删 1000 行加 LIMIT 1000。
后续预防比清理更重要
删完只是止血,真正要解决的是源头。重复数据大概率是因为缺少约束,而不是应用层没校验。
立刻补上唯一索引:
CREATE UNIQUE INDEX idx_users_email ON users(email);
如果已有重复,建索引会失败,得先清完再建。另外注意:
-
NULL值在唯一索引中不参与冲突判断(多数数据库允许多个NULL),如果业务允许空邮箱,得额外用触发器或应用层控制 - 复合唯一约束写法是
CREATE UNIQUE INDEX idx_name_phone ON users(name, phone) - 建完索引后,下次插入重复值会直接报错
ERROR 1062 (23000): Duplicate entry ... for key ...,比事后清理成本低两个数量级
真正麻烦的不是怎么删,而是删完发现下个月又冒出来——说明约束没加,或者上游系统绕过了校验逻辑。
相关文章
- 王者荣耀世界零氪玩家如何生存 07-28
- 快手极速版怎么绑定手机号 07-28
- 明日方舟和轻松小熊联动活动内容一览 07-28
- 逆战未来黎明之光 逆战未来黎明之光玩法机制与新手入门指南 07-28
- 植物大战僵尸融合版毁灭土豆地雷介绍 07-28
- 逆战未来飓风之龙 逆战未来飓风之龙武器获取方法详解 07-28