热议:删除Oracle数据库中重复数据的实际操作方案,新进度揭秘

文章导读
DELETE FROM table_name WHERE rowid NOT IN (SELECT MIN(rowid) FROM table_name GROUP BY col1, col2, col3); 这就是删除重复数据的核心语句,先按重复列分组,取最小rowid保留一条,其他删除。
📋 目录
  1. 方案一:使用ROWID
  2. 方案二:自连接删除
  3. 方案三:使用ROW_NUMBER
  4. 大表优化
  5. CTAS重建表
  6. 注意事项
A A

DELETE FROM table_name WHERE rowid NOT IN (SELECT MIN(rowid) FROM table_name GROUP BY col1, col2, col3); 这就是删除重复数据的核心语句,先按重复列分组,取最小rowid保留一条,其他删除。

方案一:使用ROWID

先查重复:select col1,col2,col3,count(*) from table group by col1,col2,col3 having count(*)>1; 然后执行delete from table where rowid not in (select min(rowid) from table group by col1,col2,col3);

方案二:自连接删除

delete from table a where rowid > (select min(rowid) from table b where b.col1=a.col1 and b.col2=a.col2 and b.col3=a.col3);

方案三:使用ROW_NUMBER

先建临时表或直接:delete from table where rowid in (select rid from (select rowid rid, row_number() over(partition by col1,col2 order by rowid) rn from table) where rn>1);

大表优化

对于大表,分批删除:delete from table where rowid in (select rid from (select rowid rid, row_number() over(partition by col1 order by rowid) rn from table where rownum<10000) where rn>1); 循环执行直到无重复。

热议:删除Oracle数据库中重复数据的实际操作方案,新进度揭秘

CTAS重建表

create table new_table as select distinct col1,col2 from old_table; drop table old_table; rename new_table to old_table; 简单高效,避免delete锁表。

注意事项

备份先!commit前检查count(*)变化,用pl/sql块加异常处理,监控undo使用。

FAQ
Q: 删除后数据丢失怎么恢复?
A: 用flashback table table_name to before drop; 或从备份恢复。
Q: 为什么用ROWID不直接用主键?
A: 重复数据主键可能不同,ROWID唯一标识物理行。
Q: 大表删除卡住怎么办?
A: 调大sort_area_size,分批或用CTAS。
Q: Oracle 12c有新方法吗?
A: 用connect by或match_recognize,但ROW_NUMBER最稳。