在 SQL 中处理重复记录涉及三个主要策略:在插入期间防止重复,识别现有重复项,以及删除或合并它们。 方法取决于是否允许在数据模型中使用重复项,以及需要如何与数据进行交互。
预防是第一道防线。 使用数据库约束(例如 UNIQUE
或 PRIMARY KEY
)来强制特定列的唯一性。 例如,将 UNIQUE (email)
添加到表定义可防止重复的电子邮件条目。 如果允许重复但需要管理,请考虑使用复合键(例如,UNIQUE (user_id, date)
以允许每个用户有多个条目,但防止重复日期)。 对于事务系统,使用 INSERT IGNORE
(MySQL) 或 ON CONFLICT DO NOTHING
(PostgreSQL) 跳过重复插入。 如果使用现有数据,则可以使用 MERGE
(在 SQL Server 中)或 UPSERT
等工具,根据唯一性检查更新现有记录或插入新记录。
识别重复项需要查询关键列中具有匹配值的行。 一种常见方法是使用 GROUP BY
和 HAVING COUNT(*) > 1
。 例如,SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1
列出出现多次的电子邮件。 窗口函数(如 ROW_NUMBER() OVER (PARTITION BY email ORDER BY id)
)也可以对重复项进行排名,从而帮助隔离特定实例(例如,保留最旧的记录)。 临时表或 CTE(公共表表达式)可用于存储分析期间的中间结果。
删除重复项通常涉及删除冗余行,同时至少保留一个实例。 例如,使用带有子查询的 DELETE
语句来为每个重复组保留最低的 id
DELETE FROM users
WHERE id NOT IN (
SELECT MIN(id) FROM users GROUP BY email
);
或者,在 CREATE TABLE AS SELECT
语句中使用 DISTINCT
以重建没有重复项的表。 对于大型数据集,批量处理或添加 status
列以标记重复项(例如,“active”与“duplicate”)可以最大限度地减少停机时间。 在批量删除之前,始终备份数据。