编程SQL/BI分析师

如何在大型SQL表中实现重复项的搜索和处理,以确保关键数据的唯一性?

用 Hintsage AI 助手通过面试

回答。

表中的重复项问题是SQL中最古老的问题之一,尤其是在互联网服务的快速增长和大量数据迁移的情况下,问题愈加严重。最初,问题通过手动解决:使用一次性脚本找到重复项并删除它们,但随着数据的增长,这种方法变得低效。

问题:在不谨慎的加载、迁移或故障的情况下,常常会产生数万个具有相同关键特征(例如,电子邮件或护照)的行。这导致集成错误、不准确的分析以及客户信任度下降。

解决方案:通过分组和窗口函数构建重复项报告;实现删除重复记录,并保留一条“正确”的记录;为关键字段添加唯一约束(UNIQUE)并定期审计。

代码示例

WITH Duplicates AS ( SELECT email, COUNT(*) AS cnt FROM users GROUP BY email HAVING COUNT(*) > 1 ) SELECT u.* FROM users u JOIN Duplicates d ON u.email = d.email ORDER BY u.email, u.id;

删除重复项(保留具有最小id的行):

DELETE FROM users WHERE id NOT IN ( SELECT MIN(id) FROM users GROUP BY email );

关键特性:

  • 使用GROUP BY,HAVING查找重复项
  • 通过NOT IN/EXISTS/ROW_NUMBER()自动化删除
  • 为关键字段引入唯一性约束

诱导性问题。

可以使用DISTINCT删除表中的重复项吗?

不可以,DISTINCT仅对查询(SELECT)有效,它不会从表中删除行。需要使用DELETE或INSERT ... SELECT与DISTINCT结合创建一个新的干净表。

命令DELETE ... WHERE id NOT IN (SELECT MIN(id) ...)能够保证删除所有重复项吗?

不可以,如果关键列中有NULL,这种查询可能会错误地保留重复项,因为NULL值比较的特性。

仅创建UNIQUE INDEX就足够确保以后不会有重复项吗?

不可以,该索引只会防止新的重复项插入,但不会影响表中已经存在的重复项。

常见错误和反模式

  • 直接根据一个列删除,未考虑NULL或复杂键
  • 缺乏对重复项的持续监控和日志记录
  • 在未清理表之前设置唯一性约束 — 会导致创建索引时出现错误

生活中的示例

消极案例

CRM系统从不同来源复制用户时未考虑电子邮件的唯一性,数据库中有50000个重复项。大量添加UNIQUE索引导致服务故障,系统停机。

优点:

  • 快速实施(在索引之前)

缺点:

  • 数据丢失,服务故障,支持中断

积极案例

工程师定期通过专业报告分析重复项,清理数据库,创建唯一索引。在迁移新数据之前进行验证。

优点:

  • 清晰的关键数据
  • 最小化分析中的错误

缺点:

  • 需要监控和程序自动化的设置