`

在Oracle中如何利用Rowid查找和删除表中的重复记录-数据库专栏,ORACLE

阅读更多
平时工作中可能会遇到当试图对库表中的某一列或几列创建唯一索引时,系统提示 ora-01452 :不能创建唯一索引,发现重复记录。

下面总结一下几种查找和删除重复记录的方法(以表cz为例):
表cz的结构如下:
sql> desc cz
name                                      null?    type
----------------------------------------- -------- ------------------

c1                                                 number(10)
c10                                                number(5)
c20                                                varchar2(3)

删除重复记录的方法原理:
(1).在oracle中,每一条记录都有一个rowid,rowid在整个数据库中是唯一的,rowid确定了每条记录是在oracle中的哪一个数据文件、块、行上。

(2).在重复的记录中,可能所有列的内容都相同,但rowid不会相同,所以只要确定出重复记录中那些具有最大rowid的就可以了,其余全部删除。

重复记录判断的标准是:
c1,c10和c20这三列的值都相同才算是重复记录。

经查看表cz总共有16条记录:
sql>set pagesize 100
sql>select * from cz;

         c1        c10 c20
---------- ---------- ---
         1          2   dsf
         1          2   dsf
         1          2   dsf
         1          2   dsf
         2          3   che
         1          2   dsf
         1          2   dsf
         1          2   dsf
         1          2   dsf
         2          3   che
         2          3   che
         2          3   che
         2          3   che
         3          4   dff
         3          4   dff
         3          4   dff
         4          5   err
         5          3   dar
         6          1   wee
         7          2   zxc

20 rows selected.

1.查找重复记录的几种方法:
(1).sql>select * from cz group by c1,c10,c20 having count(*) >1;
        c1        c10 c20
---------- ---------- ---
         1          2   dsf
         2          3   che
         3          4   dff

(2).sql>select distinct * from cz;

        c1        c10 c20
---------- ---------- ---
         1          2   dsf
         2          3   che
         3          4   dff

(3).sql>select * from cz a where rowid=(select max(rowid) from cz where c1=a.c1 and c10=a.c10 and c20=a.c20);
        c1        c10 c20
---------- ---------- ---
         1          2   dsf
         2          3   che
         3          4   dff

2.删除重复记录的几种方法:
(1).适用于有大量重复记录的情况(在c1,c10和c20列上建有索引的时候,用以下语句效率会很高):
sql>delete cz where (c1,c10,c20) in (select c1,c10,c20 from cz group by c1,c10,c20 having count(*)>1) and rowid not in
(select min(rowid) from cz group by c1,c10,c20 having count(*)>1);

sql>delete cz where rowid not in(select min(rowid) from cz group by c1,c10,c20);

(2).适用于有少量重复记录的情况(注意,对于有大量重复记录的情况,用以下语句效率会很低):
sql>delete from cz a where a.rowid!=(select max(rowid) from cz b where a.c1=b.c1 and a.c10=b.c10 and a.c20=b.c20);

sql>delete from cz a where a.rowid<(select max(rowid) from cz b where a.c1=b.c1 and a.c10=b.c10 and a.c20=b.c20);

sql>delete from cz a where rowid <(select max(rowid) from cz  where c1=a.c1 and c10=a.c10 and c20=a.c20);

(3).适用于有少量重复记录的情况(临时表法):
sql>create table test as select distinct * from cz; (建一个临时表test用来存放重复的记录)

sql>truncate table cz;  (清空cz表的数据,但保留cz表的结构)

sql>insert into cz select * from test;  (再将临时表test里的内容反插回来)

(4).适用于有大量重复记录的情况(exception into 子句法):
采用alter table 命令中的 exception into 子句也可以确定出库表中重复的记录。这种方法稍微麻烦一些,为了使用“excepeion into ”子句,必须首先创建 exceptions 表。创建该表的 sql 脚本文件为 utlexcpt.sql 。对于win2000系统和 unix 系统, oracle 存放该文件的位置稍有不同,在win2000系统下,该脚本文件存放在$oracle_home\ora90\rdbms\admin 目录下;而对于 unix 系统,该脚本文件存放在$oracle_home/rdbms/admin 目录下。

具体步骤如下:
sql>@?/rdbms/admin/utlexcpt.sql

table created.

sql>desc exceptions
name                                      null?    type
----------------------------------------- -------- --------------

row_id                                             rowid
owner                                              varchar2(30)
table_name                                 varchar2(30)
constraint                                   varchar2(30)

sql>alter table cz add constraint  cz_unique unique(c1,c10,c20) exceptions into exceptions; 
                                                      *
error at line 1:
ora-02299: cannot validate (test.cz_unique) - duplicate keys found

sql>create table dups as select * from cz where rowid in (select row_id from exceptions);

table created.

sql>select * from dups;

        c1        c10 c20
---------- ---------- ---
         1          2   dsf
         1          2   dsf
         1          2   dsf
         1          2   dsf
         2          3   che
         1          2   dsf
         1          2   dsf
         1          2   dsf
         1          2   dsf
         2          3   che
         2          3   che
         2          3   che
         2          3   che
         3          4   dff
         3          4   dff
         3          4   dff

16 rows selected.

sql>select row_id from exceptions;

row_id
------------------
aaahd/aaiaaaadsaaa
aaahd/aaiaaaadsaab
aaahd/aaiaaaadsaac
aaahd/aaiaaaadsaaf
aaahd/aaiaaaadsaah
aaahd/aaiaaaadsaai
aaahd/aaiaaaadsaag
aaahd/aaiaaaadsaad
aaahd/aaiaaaadsaae
aaahd/aaiaaaadsaaj
aaahd/aaiaaaadsaak
aaahd/aaiaaaadsaal
aaahd/aaiaaaadsaam
aaahd/aaiaaaadsaan
aaahd/aaiaaaadsaao
aaahd/aaiaaaadsaap

16 rows selected.

sql>delete from cz where rowid in ( select row_id from exceptions);

16 rows deleted.

sql>insert into cz select distinct * from dups;

3 rows created.

sql>select *from cz;

        c1        c10 c20
---------- ---------- ---
         1          2   dsf
         2          3   che
         3          4   dff
         4          5   err
         5          3   dar
         6          1   wee
         7          2   zxc

7 rows selected.

从结果里可以看到重复记录已经删除。
分享到:
评论

相关推荐

    Oracle中用Rowid查找和删除表中的重复记录

    ### Oracle中用Rowid查找和删除表中的重复记录 在Oracle数据库管理中,处理重复记录是一项常见的需求,尤其是在数据量较大的情况下。本文将详细介绍如何利用Rowid这一特性来有效地查找和删除表中的重复记录。 ####...

    Oracle数据库删除表中重复记录的方法三则.txt

    ### Oracle数据库删除表中重复记录的方法 在Oracle数据库管理中,经常会遇到需要处理表中的重复数据的情况。重复数据不仅会占用不必要的存储空间,还可能导致数据统计错误或业务逻辑混乱等问题。因此,掌握如何有效...

    Oracle数据库rowid深入探析.pdf

    伪列类似于数据表的列,建立表时,数据库会自动为每个表建立rowid列,但它实际上不存储在表中,因此,当用desc命令来查看任何一个表的结构时,都不会显示有rowid这一列存在。 rowid的概念 在Oracle官方文档中,对...

    mysql虚拟了一个rowid(类似跟oracle的rowid)--SQL语句.sql

    mysql虚拟了一个rowid(类似跟oracle的rowid)--SQL语句

    Oracle中查找和删除重复记录方法

    删除重复记录的方法原理:在Oracle中,每一条记录都有一个rowid,rowid在整个数据库中是唯一的,rowid确定了每条记录是在Oracle中的哪一个数据文件、块、行上。在重复的记录中,可能所有列的内容都相同,但rowid不会...

    怎样删除数据库中重复记录

    删除数据库中重复记录是数据库管理中一个常见的问题,特别是在数据量庞大的时候。今天,我们将讨论删除数据库中重复记录的经典方法,包括使用 SQL 语句和其他技巧。 查找表中多余的重复记录 要删除数据库中重复...

    如何高效删除Oracle数据库中的重复数据

    ### 如何高效删除Oracle数据库中的重复数据 在Oracle数据库管理中,经常会出现因各种原因导致的数据重复问题。这些重复数据不仅占用存储空间、降低查询效率,还可能导致数据分析时出现错误的结果。因此,学会如何...

    试论Rowid在Oracle数据库中的应用.pdf

    每行记录在Oracle数据库中都会有一个Rowid,相当于一个物理地址,即使该行数据在数据库中发生了迁移,其Rowid也不会改变。在处理大量数据的情况下,对Rowid的使用可以大幅提高数据访问的效率。 在Oracle数据库中,...

    wxh Oracle数据库删除重复记录的方法

    根据给定的文件标题、描述和部分内容,我们可以深入探讨Oracle数据库中删除重复记录的方法,这对于维护数据完整性和提高系统性能至关重要。以下将详细介绍几种在Oracle数据库中有效删除重复记录的技术。 ### 1. ...

    浅析Rowid在Oracle数据库中的应用.pdf

    在数据库设计和管理中,掌握Rowid的特性有助于优化表结构,合理利用索引,提高数据存取效率。例如,通过分析Rowid的分布,可以评估表空间的使用情况,预测可能的热点问题,从而进行必要的表分区或索引策略调整。 ...

    Oracle8-数据库系统.ppt

    位图索引可以快速找到表记录,并且可以将位的位置转换为实际的 ROWID。位图索引的创建语法为:create bitmap index 索引名 on 表名(列名)。位图索引可以合并简化查询条件,从而过滤被访问的数据集合。 簇索引是一种...

    使用Oracle查询并删除重复记录的SQL语句

    在实际应用中,删除重复记录是非常常见的操作,特别是在数据导入、数据整合和数据清洁等场景中。Oracle数据库提供了多种方式来查询和删除重复记录,本文将详细介绍这些方法。 查找表中多余的重复记录 使用子查询...

    Oracle查询重复数据并删除,只保留一条记录.docx

    最后,我们可以使用以下语句来查找表中多余的重复记录(多个字段),不包含 rowid 最小的记录: ```sql select * from R_RESOURCE_DETAILS a where (a.FIELD_CODE,a.DTA_ITEM_NAME) in (select FIELD_CODE,DTA_ITEM...

    在oracle中灵活使用Rownum和rowId

    在Oracle数据库中,`ROWNUM` 和 `ROWID` 是两个非常重要的概念,它们可以帮助我们在查询数据时实现更灵活的数据管理。本文将详细介绍这两个概念的区别及其使用方法,并通过示例来帮助读者更好地理解。 #### 一、...

    oracle删除重复记录性能分析

    在数据库管理中,经常会遇到数据清理的需求,尤其是在Oracle数据库中处理重复记录时。本文旨在通过对比几种不同的方法来删除Oracle中的重复记录,并分析其性能差异,从而为数据库管理员提供有效的解决方案。 #### ...

    plsql删除重复记录

    特别是在大型企业级应用中,由于各种原因(如数据导入错误、系统故障等),数据库表中可能会出现大量的重复记录,这对数据的准确性和系统的性能都会产生负面影响。因此,掌握如何有效地识别并删除这些重复记录显得尤...

    Oracle数据库学习指南

    30.删除表内重复记录的方法 31.数据库安全性策略 32.数据库的查询优化技术. 33.提高C-S系统性能的一些方法 34.提高ORACLE数据库系统import性能 35.外部联接的用法 36.性能调试的一般问题 37.优化 38...

    oracle中如何删除重复数据

    在Oracle数据库中,删除重复数据是一项常见的数据清洗任务,尤其当表设计不当时,重复数据可能导致数据不一致和分析错误。以下将详细解释如何在Oracle中处理这两种类型的重复数据问题:部分字段重复和完全重复记录。...

Global site tag (gtag.js) - Google Analytics