`
deejay
  • 浏览: 145329 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

oracle 查找 删除 重复记录

阅读更多

总结了一下删除重复记录的方法,以及每种方法的优缺点。
假设表名为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 not in (select max(b.rowid) from tbl b where a.col1=b.col1 and a.col2 = b.col2);//这里max使用min也可以
或者用下面的语句
delete from tbl a where rowid < (select max(b.rowid) from tbl b where a.col1=b.col1 and a.col2 = b.col2

4、利用group by,提高效率
平时工作中可能会遇到当试图对库表中的某一列或几列创建唯一索引时,系统提示 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.

从结果里可以看到重复记录已经删除。
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   nin(rowid) from tbl group by col1,col2 having   count(*) > 1)

 

 

查找某一字段(titlehash) 重复的所有记录:

select t.id, t.title
from proposal t
WHERE t.titlehash in
(select DISTINCT a.titlehash from proposal a,proposal b
where a.rowid>b.rowid and a.titlehash=b.titlehash )

分享到:
评论

相关推荐

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

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

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

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

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

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

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

    通过上述方法,我们可以有效地在Oracle数据库中查找和删除重复记录。选择哪种方法取决于具体的业务场景和技术需求。例如,在数据量非常大的情况下,可能更倾向于使用基于Rowid的比较或者临时表法,以减少数据库的...

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

    ### Oracle查询重复数据与删除重复记录方法 #### 一、查询重复数据 ##### 1. 使用ROWID方法 ROWID是Oracle中一个特殊的数据类型,它代表了表中每一条记录在物理存储上的唯一地址。利用ROWID可以非常高效地查询和...

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

    在 Oracle 中,我们可以使用 GROUP BY 语句来查找重复记录。假设我们要根据 FIELD_CODE 字段来判断重复记录,可以使用以下语句: ```sql select * from R_RESOURCE_DETAILS where FIELD_CODE in(select FIELD_CODE ...

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

    删除重复记录时,通常保留一个代表性的记录,例如保留 `ROWID` 最小的记录。可以使用以下 SQL 语句: ```sql DELETE from 表 WHERE (id) IN ( SELECT id FROM 表 GROUP BY id HAVING COUNT(id) &gt; 1) AND ...

    ORACLE重复记录查询.docxORACLE

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

    ORACLE查询删除重复记录三种方法

    例如,如果我们有一个名为table1的表,包含name1和name2字段,我们可以这样查询和删除重复记录: 查询数据: ```sql SELECT * FROM table1 a WHERE rowid != (SELECT MAX(rowid) FROM table1 b WHERE a.name1 = ...

    oracle删除重复数据方法

    以下是一些针对不同情况的 Oracle SQL 语句,用于查找和删除重复数据: 1. **根据单个字段删除重复数据:** 当我们需要删除基于特定字段(如 `peopleId`)的重复数据时,可以先找出这些重复项,然后删除除最小 ...

    Oracle 查找与删除表中重复记录的步骤方法

    本篇文章将详细介绍如何在Oracle中查找并删除重复记录。 首先,查找重复记录通常涉及使用`GROUP BY`和`HAVING`子句。例如,如果我们有一个名为`CFA`的表,包含`businessid`、`customer`、`branchcode`和`data_date`...

    Oracle删除重复的数据,Oracle数据去重复

    - `DISTINCT`关键字可以用于查询结果集中去除重复行,但不适用于实际删除重复数据。 - 可以创建唯一索引,阻止新的重复数据插入。 - 使用`MERGE`语句结合`WITH`子句也可以处理重复数据问题,提供更灵活的策略。 ...

    oracle查询重复数据和删除重复记录示例分享

    这些示例展示了在Oracle中处理重复数据的基本方法,包括查询重复数据以及根据特定条件保留或删除重复记录。在实际应用中,需要根据业务需求和数据情况灵活调整这些SQL语句。在执行删除操作时,务必谨慎,确保有备份...

    Oracle重复数据清理

    5. 特定字段的过滤:在上述提供的示例中,虽然某些过滤条件已被注释掉,但可以通过在查询中加入特定的过滤条件来限制要查找和删除重复数据的范围,例如只针对特定的车辆编号或分类编号进行操作。 6. 注意数据迁移的...

    如何查出同一张表中字段值重复的记录

    #### 1.2 删除重复记录 如果需要删除这些重复记录,可以使用以下 SQL 语句: ```sql DELETE FROM table1 a WHERE ROWID != (SELECT MAX(ROWID) FROM table1 b WHERE a.name1 = b.name1 AND a.name2 = b.name2); ```...

    oracle学习及练习语句

    本文将深入探讨在"Oracle学习及练习语句"主题中涉及的关键知识点,包括DDL语句、联系表设计、ROWNUM的使用以及如何查询和删除重复记录。 1. DDL(Data Definition Language)语句:在Oracle中,DDL用于创建、修改或...

Global site tag (gtag.js) - Google Analytics