`
coconut_zhang
  • 浏览: 541801 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

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

阅读更多

平时工作中可能会碰到当试图对库表中的某一列或几列创建唯一索引时,系统提示 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_HOMEOra90rdbmsadmin 目录下;而对于 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中查找和删除重复记录方法

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

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

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

    Oracle数据库rowid深入探析.pdf

    "Oracle数据库rowid深入探析" Oracle数据库rowid是Oracle数据库中一个重要的概念,也是...Oracle数据库rowid是一个非常重要的概念,它可以帮助开发者更好地理解Oracle数据库的工作机理,并提高开发效率和数据库性能。

    Oracle查询重复数据与删除重复记录方法

    使用ROWID删除重复记录时,可以采用与查询重复记录类似的方法,但操作变为删除。 ```sql DELETE FROM table1 a WHERE ROWID NOT IN (SELECT MIN(ROWID) FROM table1 b WHERE a.name1 = b.name1 AND a.name2 = b....

    Oracle查询重复数据与删除重复记录方法(txt)

    本文将详细介绍几种常用的查询和删除Oracle数据库中重复记录的方法。 #### 一、查询重复数据 1. **使用ROWID** ROWID是Oracle提供的一种特殊数据类型,它表示表中行的物理地址。通过ROWID可以快速定位到表中的某...

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

    这条语句将查找 R_RESOURCE_DETAILS 表中所有重复的 FIELD_CODE 和 DTA_ITEM_NAME 字段,并返回所有重复记录,但排除 rowid 最小的记录。 本文介绍了如何使用 Oracle 查询重复数据并删除,只保留一条记录。这种方法...

    oracle删除重复记录性能分析

    ### Oracle删除重复记录性能分析 #### 一、背景与需求 在数据库管理中,经常会遇到数据清理的需求,尤其是在Oracle数据库中处理重复记录时。本文旨在通过对比几种不同的方法来删除Oracle中的重复记录,并分析其...

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

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

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

    除了使用子查询和RowId外,还有其他方法可以用来查找和删除重复记录。例如,我们可以使用游标来删除重复记录: ```sql declare @max integer, @id integer declare cur_rows cursor local for select 主字段, count...

    plsql删除重复记录

    ### PL/SQL删除Oracle数据库中的重复记录方法详解 ...通过上述步骤,你可以有效地识别并删除Oracle数据库中的重复记录,从而保持数据的一致性和准确性。这种方法不仅适用于简单的场景,对于复杂的业务环境也同样适用。

    ORACLE重复记录查询.docxORACLE

    本文将详细探讨如何在Oracle中查询和删除重复记录,主要聚焦于单个字段和多个字段的情况。 1. **单个字段重复记录查询** 当我们需要根据单个字段(如`peopleId`)查找重复记录时,可以使用以下SQL语句: ```sql ...

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

    使用ROWID删除重复记录 ROWID是Oracle提供的一种特殊的数据类型,用于唯一标识表中的每一行。利用ROWID,可以有效地删除重复记录。 ```sql delete from tbl where rowid in ( select a.rowid from tbl a, tbl b ...

    解决Oracle删除重复数据只留一条的方法详解

    查询及删除重复记录的SQL语句1、查找表中多余的重复记录,重复记录是根据单个字段(Id)来判断select * from 表 where Id in (select Id from 表 group by Id having count(Id) &gt; 1)2、删除表中多余的重复记录,...

    查询及删除重复记录的SQL语句.

    Oracle 数据库提供了一系列 SQL 语句来帮助我们查询和删除这些重复的记录。以下是一些常用的 SQL 技巧,用于处理重复记录的问题。 1. **查询重复记录**: 当我们想找出基于单一字段(如 `Id`)的重复记录时,可以...

    查找删除重复记录

    以上代码通过组合`peopleId`和`seq`字段来查找重复记录,并使用`rowid`来保留每组中的一个记录。 #### 知识点七:使用临时表处理重复记录 除了直接使用子查询之外,还可以使用临时表来处理重复记录。这种方法可以...

    数据库 查询删除重复数据

    数据库查询删除重复数据是数据库管理中的一项重要操作,旨在查找和删除表中的重复记录。重复记录是根据单个字段或多个字段来判断的。下面介绍几种查找和删除重复记录的方法。 根据单个字段查找和删除重复记录 可以...

Global site tag (gtag.js) - Google Analytics