`

oracle-快速删除重复的记录

阅读更多
oracle-快速删除重复的记录

转:http://dev.csdn.net/author/Rayfly/b850da865b3b4cc89008a2004dad56fc.html

oracle-快速删除重复的记录

文/Ray

对此,总结了一下删除重复记录的方法,以及每种方法的优缺点。

为了陈诉方便,假设表名为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);//这里如果把max换成min的话,前面的where子句中需要把"<"改为">"


跟上面的方法思路基本是一样的,不过使用了group by,减少了显性的比较条件,提高效率。SQL语句如下:

还有一种方法,对于表中有重复记录的记录比较少的,并且有索引的情况,比较适用。假定col1,col2上有索引,并且tbl表中有重复记录的记录比较少,SQL语句如下


4、利用group by,提高效率


=================

转:http://dev.csdn.net/author/housisong/8f2bd476-b071-49ee-bc55-1a96ed513143.html

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



平时工作中可能会遇到当试图对库表中的某一列或几列创建唯一索引时,系统提示 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)

分享到:
评论

相关推荐

    oracle中如何删除重复的记录

    要删除Oracle数据库表中的重复记录,有几种方法可以采用: ##### 方法一:使用子查询与DELETE语句 这种方法适用于只需要删除重复记录中的某些行的情况。步骤如下: 1. **找出重复的记录**:首先,我们需要找到...

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

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

    oracle删除重复记录性能分析

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

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

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

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

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

    OracleSQL实例-删除重复数据行留最新日期实例.pdf

    在Oracle SQL中,删除重复数据并保留最新日期的实例是一个常见的数据清理任务,尤其是在具有历史记录或事务数据的数据库中。这个实例展示了如何通过SQL查询有效地处理这种情况。在这个例子中,我们有一个名为`abc`的...

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

    ### Oracle查询重复数据与删除重复记录方法 在Oracle数据库中,有时我们需要找出并处理重复的数据。这不仅可以提高数据质量,还能提升查询效率。本文将详细介绍几种常用的查询和删除Oracle数据库中重复记录的方法。...

    oracle快速删除重复的记录

    Oracle 快速删除重复记录 在 Oracle 数据库中,删除重复记录是一项常见的操作,尤其是在大型数据表中。删除重复记录可以提高数据的准确性和一致性。本文总结了四种删除重复记录的方法,每种方法都有其优缺点。 ...

    plsql删除重复记录

    ### PL/SQL删除Oracle数据库中的重复记录方法详解 在日常的数据库管理与维护工作中,我们经常会遇到需要处理数据表中的重复记录的情况。特别是在大型企业级应用中,由于各种原因(如数据导入错误、系统故障等),...

    oracle删除重复记录

    本文将详细介绍如何在Oracle数据库中有效地删除表内的重复记录。 ### 一、理解重复记录 在数据库中,重复记录是指具有相同字段值的一组记录。例如,在一个员工表中,如果有多个记录拥有相同的姓名、职位等信息,则...

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

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

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

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

    Oracle--vb代码.rar

    Oracle数据库是全球广泛使用的大型关系型数据库管理系统,它提供了丰富的功能和高性能的数据库解决方案。而VB,即Visual Basic,是Microsoft开发的一种可视化编程工具,它以其简单易学、高效的编程特性,深受程序员...

    删除数据表中重复记录

    本文将详细介绍如何在不同的数据库系统(如MySQL、SQL Server、Oracle等)中删除重复记录。 #### SQL删除重复记录的基本思路 删除重复记录的核心思想是先识别出哪些记录是重复的,然后通过某种方式将这些重复记录...

    oracle中如何删除重复数据

    以下将详细解释如何在Oracle中处理这两种类型的重复数据问题:部分字段重复和完全重复记录。 一、部分字段重复数据的删除 1. 查询重复数据: 使用`GROUP BY`和`HAVING`子句可以找出具有相同值的字段组合。例如,...

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

    接下来,我们可以使用 DELETE 语句来删除这些重复记录,但保留 rowid 最小的记录: ```sql delete from R_RESOURCE_DETAILS where (FIELD_CODE) in (select FIELD_CODE from R_RESOURCE_DETAILS group by FIELD_...

    Oracle-ERP开发笔记

    - 删除重复的记录是数据清洗的重要环节之一。 **12. 查询具有相同薪水的职工** - 通过JOIN或子查询等技术查询具有相同薪水的员工。 **13. Oracle死锁之解决方法** - 解决死锁的方法通常包括回滚部分事务或调整锁定...

    Oracle删除表中的重复数据

    ### Oracle删除表中的重复数据方法 在Oracle中删除表中的重复数据,可以采用多种策略,但通常涉及创建一个临时表来保存去重后的数据,然后用这个临时表覆盖原始表。这种方法可以避免直接修改原表带来的风险,确保...

    oracle下如何删除重复数据的几种方法

    无论是部分字段重复还是完全重复的记录,都可以通过创建临时表的方式提高删除重复记录的效率。此外,在处理重复数据时,还应考虑到保留最新或最旧记录的需求,利用`ROWID`等特性可以轻松实现这一点。总之,合理地...

Global site tag (gtag.js) - Google Analytics