在ACCESS数据库的日常使用中,表中出现重复记录是很常见的情况,比如批量导入数据时没有做去重校验,或者业务操作过程中产生了冗余数据。这些重复记录会干扰正常的查询统计,也会占用不必要的存储空间,使用SQL语句删除重复记录是最高效的处理方式,主要有两种常用的实现方法。

方法一:利用distinct关键字重建表
这种方法的思路是先通过SELECT DISTINCT语句从原表中查询出所有不重复的记录,然后将这些记录存入一个新的临时表,最后删除原表,把临时表重命名为原表名,这样就完成了重复记录的删除。
假设我们有一个名为user_info的表,表结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | 自动编号 | 主键 |
| user_name | 文本 | 用户名 |
| user_age | 数字 | 用户年龄 |
如果我们要删除user_name和user_age都重复的记录,可以按照以下步骤操作:
第一步,创建临时表并插入去重后的数据:
-- 创建临时表,结构和原表一致
CREATE TABLE user_info_temp (
id COUNTER PRIMARY KEY,
user_name TEXT(50),
user_age INTEGER
);
-- 插入去重后的数据,distinct会对所有选中字段的组合去重
INSERT INTO user_info_temp (user_name, user_age)
SELECT DISTINCT user_name, user_age FROM user_info;
第二步,删除原表,将临时表重命名为原表名:
-- 删除原表 DROP TABLE user_info; -- 重命名临时表为原表名 ALTER TABLE user_info_temp RENAME TO user_info;
这种方法的优点是逻辑简单,适合全表去重的场景,缺点是如果原表有主键外的其他约束、索引或者关联关系,重建表后需要重新配置这些内容。
方法二:利用group by分组删除重复记录
这种方法的思路是通过GROUP BY语句对重复字段进行分组,找到每组中需要保留的记录(比如保留id最小的那条),然后删除不在这个保留范围内的重复记录,不需要重建表,更适合只需要删除部分重复记录的场景。
还是以上面的user_info表为例,我们要删除user_name和user_age重复的记录,只保留每组中id最小的那条,SQL语句如下:
DELETE FROM user_info
WHERE id NOT IN (
-- 分组查询每组中最小的id,作为要保留的记录id
SELECT MIN(id)
FROM user_info
GROUP BY user_name, user_age
);
这段语句的执行逻辑是:子查询先按照user_name和user_age分组,每组计算出最小的id,也就是要保留的记录的id,然后主查询删除所有id不在这个保留列表中的记录,剩下的就是每组只保留一条的去重结果。
这种方法的优点是不需要重建表,不会丢失原表的约束、索引和关联关系,操作更轻量,缺点是在数据量特别大的时候,子查询的执行效率可能会稍低,需要合理建立索引优化。
两种方法的适用场景对比
我们可以根据实际需求选择合适的方法:
- 如果需要全表去重,且原表没有复杂的关联和约束,优先选择distinct重建表的方法,操作更直观。
- 如果只需要删除部分重复记录,或者原表有复杂的约束、索引、关联关系,优先选择group by分组删除的方法,避免额外的工作量。
在操作之前,建议先备份原表数据,避免误删重要数据导致损失。如果不确定SQL语句的执行效果,可以先把删除语句改成查询语句,验证要删除的记录是否符合预期,再执行删除操作。