在oracle数据库的实际使用过程中,部分表在创建时未添加主键、唯一约束等限制条件,随着业务数据的不断写入,很容易出现多条完全相同的重复记录。这些重复数据不仅会浪费存储空间,还会干扰查询统计、数据同步等操作的准确性,因此需要及时清理。下面介绍几种适用于无约束表的重复记录删除方法。

方法一:利用rowid特性删除重复记录
oracle中每一行数据都有唯一的rowid标识,即使所有字段值完全相同,rowid也不会重复。我们可以先按重复字段分组,保留每组中rowid最小的一条记录,删除其余重复记录。
假设存在表test_table,重复判断的字段为col1、col2、col3,删除重复记录的示例如下:
-- 删除test_table表中col1、col2、col3都重复的记录,保留每组rowid最小的一条
DELETE FROM test_table
WHERE rowid NOT IN (
-- 按重复字段分组,取每组最小的rowid
SELECT MIN(rowid)
FROM test_table
GROUP BY col1, col2, col3
);
这种方法的优点是逻辑简单,执行效率较高,适合重复数据量不大的场景。如果重复字段较多,只需要在GROUP BY后补充对应的字段即可。
方法二:使用子查询关联删除重复记录
如果需要更灵活的控制,比如指定保留某条符合条件的记录,可以使用子查询关联的方式删除重复数据。同样是test_table表,示例代码如下:
-- 关联子查询删除重复记录,保留每组中id最小的一条(假设表有id字段)
DELETE FROM test_table t1
WHERE EXISTS (
SELECT 1
FROM test_table t2
WHERE t1.col1 = t2.col1
AND t1.col2 = t2.col2
AND t1.col3 = t2.col3
AND t1.id > t2.id
);
上述代码中,通过关联条件匹配重复记录,并且只删除id更大的重复记录,从而保留每组中id最小的一条。如果没有id字段,也可以替换为rowid的比较。
方法三:通过临时表迁移去重数据
当表中重复数据量非常大时,直接删除可能会导致undo表空间不足或者执行时间过长,此时可以先创建临时表存储去重后的数据,再替换原表。
具体步骤如下:
- 第一步:创建临时表,插入去重后的数据
- 第二步:清空原表数据
- 第三步:将临时表的数据插回原表
示例代码如下:
-- 第一步:创建临时表并插入去重数据 CREATE TABLE test_table_temp AS SELECT col1, col2, col3 FROM test_table GROUP BY col1, col2, col3; -- 第二步:清空原表 TRUNCATE TABLE test_table; -- 第三步:将去重后的数据插回原表 INSERT INTO test_table (col1, col2, col3) SELECT col1, col2, col3 FROM test_table_temp; -- 第四步:删除临时表(可选) DROP TABLE test_table_temp;
这种方法的优点是执行过程更稳定,不会影响原表的表结构、索引、权限等属性,适合大表重复数据清理场景。
注意事项
在删除重复记录前,建议先执行查询语句确认要删除的数据范围,避免误删有效数据:
-- 查询重复记录的数量和明细 SELECT col1, col2, col3, COUNT(*) FROM test_table GROUP BY col1, col2, col3 HAVING COUNT(*) > 1;
另外,删除操作执行前最好备份表数据,防止操作失误导致数据无法恢复。如果表数据量较大,建议在业务低峰期执行删除操作,避免影响正常业务运行。
oracledelete_duplicate_recordsrowidgroup_bysubquery修改时间:2026-06-30 20:57:16