Oracle ——删除表中重复记录

文章介绍了在Oracle数据库中删除重复数据的四种策略:通过创建临时表、利用ROWID、使用MAX或MIN函数以及运用GROUPBY。这些方法各有优缺点,适用于不同场景,如数据量大小和重复数据的频率等。

        为了方便,假设表名为Tbl,表中有三列col1,col2,col3,其中col1,col2是主键,并且,col1,col2上加了索引重复数据删除

1、通过创建临时表

·        把数据先导入到一个临时表中,然后删除原表的数据,再把数据导回原表。SQL语句如下:

creat table tbl_tmp (select distinct * from tbl);

truncate table tbl;//清空表记录

insert into tbl select * from tbl_tmp;//将临时表中的数据插回来重复数据删除。

        这种方法可以实现需求,但是很明显,对于一个千万级记录的表,这种方法很慢,在生产系统中,这会给系统带来很大的开销,不可行重复数据删除

2、利用rowid

       在oracle中,每一条记录都有一个rowid,rowid在整个数据库中是唯一的,rowid确定了每条记 录是oracle中的哪一个数据文件、块、行上重复数据删除。在重复的记录中,可能所有列的内容都相同,但rowid不会相同。SQL语句如下:

delete from tbl

        where rowid in (

                select a.rowid from tbl a, tbl b

                        where a.rowid>b.rowid

                        and a.col1=b.col1

                        and a.col2 = b.col2

        );

        如果已经知道每条记录只有一条重复的,这个sql语句适用重复数据删除。但是如果每条记录的重复记录有N条,这个N是未知的,就要考虑适用下面这种方法了。

3、利用max或min函数

        这里也要使用rowid,与上面不同的是结合max或min函数来实现重复数据删除。SQL语句如下:

delete from tbl a

        where rowid < (

                select max(b.rowid) from tbl b

                        where a.col1=b.col1

                        and a.col2 = b.col2

                );//这里如果把max换成min的话重复数据删除,前面的where子句中需要把"<"改为">"

 或者用下面的语句:

delete from tbl a

        where rowid not in (

                select max(b.rowid) from tbl b

                        where a.col1=b.col1

                        and a.col2 = b.col2

        );//这里max使用min也可以

 4、使用group by

        对于表中有重复记录的记录比较少的,并且有索引的情况,比较适用重复数据删除。假定col1,col2上有索引,并且tbl表中有重复记录的记录比较少,减少了显性的比较条件,提高效率重复数据删除。SQL语句如下:

delete from tbl

        where rowid not in (

                select max(rowid) from tbl t

                        group by t.col1, t.col2

        );

delete from tbl

        where (col1, col2) in (

                select col1,col2 from tbl

                        group by col1,col2

                        having count(*) >1

        )

        and rowid not in (

                select min (rowid) from tbl

                        group by col1,col2

                        having count(*) >1

        )

### 查找和处理Oracle数据库中的重复数据 #### 查找重复数据SQL语句 在Oracle数据库中,可以通过`GROUP BY`和`HAVING`子句来查找中存在的重复记录。假设有一个名为`TEST_TABLE`的,其中有一列`CODE`可能包含重复值,则可以使用以下SQL语句找出重复项: ```sql SELECT CODE, COUNT(*) FROM TEST_TABLE GROUP BY CODE HAVING COUNT(*) > 1; ``` 此查询会返回所有具有重复`CODE`值的记录及其出现次数[^1]。 如果需要查看具体的重复行,还可以加入其他字段以便更清楚地了解哪些行是重复的。例如: ```sql SELECT * FROM TEST_TABLE t1 WHERE EXISTS ( SELECT 1 FROM TEST_TABLE t2 WHERE t1.CODE = t2.CODE AND t1.ROWID != t2.ROWID ); ``` 这段代码利用了`EXISTS`关键字以及`ROWID`伪列(每行唯一的标识符),从而筛选出那些存在至少一条相同`CODE`但不同`ROWID`的记录。 #### 处理重复数据的方法 对于已经存在的重复数据,有几种常见的方法来进行清理或管理: 1. **删除多余的副本** 如果只需要保留一份每个唯一组合的数据,那么可以从冗余记录集中移除多余的部分。比如基于前面提到的第一种方式找到的所有重复项目,执行如下命令即可清除它们之一以外的所有实例: ```sql DELETE FROM TEST_TABLE WHERE ROWID NOT IN ( SELECT MIN(ROWID) FROM TEST_TABLE GROUP BY CODE ); ``` 这里采用了嵌套查询结构,在外层DELETE指令的作用下只留下各组内的最小ROWID对应的那条原始记录[^2]。 2. **创建唯一索引或者约束防止未来再次发生此类情况** 当前内可能存在违反业务逻辑的情况——即某些特定属性不应该被多次录入却出现了这种情况。此时应当考虑引入唯一性保障机制以杜绝后续类似错误的发生。具体做法包括但不限于定义UNIQUE KEY或是PRIMARY KEY等强制性的限制条件。然而需要注意的是当尝试施加这样的规则到已含有冲突值的目标列上去的时候可能会遇到ORA-02299类型的异常提示因为检测到了现存违背新规定的内容所以无法完成验证过程。对此可先采用NOVALIDATE选项跳过现有校验再逐步修正历史遗留问题后再启用完全合规模式[^4][^5]: ```sql ALTER TABLE TEST_TABLE ADD CONSTRAINT UK_TEST_TABLE_CODE UNIQUE (CODE) NOVALIDATE; -- 后续手动调整完毕之后重新激活全面检验状态 ALTER INDEX UK_TEST_TABLE_CODE REBUILD VALIDATE STRUCTURE CASCADE; ``` 3. **运用正则达式辅助复杂匹配场景下的去重工作** 面向更加棘手的情形比如说涉及非标准化格式字符串对比等情况时,借助内置的支持Perl风格语法特性的REGEXP系列功能将会非常有用处。它允许我们构建高度灵活精确的搜索模板进而定位满足预期特征的对象集合并实施相应的处置措施[^3]。 #### 总结说明 综上所述,针对Oracle环境下关于如何识别与治理重复资料这一主题给出了若干实用建议方案涵盖了基础层面的操作技巧直至高级别的定制化需求应对策略。希望以上分享能够帮助解决实际应用过程中所面临的相关挑战。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值