`

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 from 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 fron 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查询重复数据与删除重复记录方法

    以上几种方法都可以有效地帮助我们查找和删除Oracle数据库中的重复记录。选择哪种方法取决于具体的业务需求和数据规模。ROWID方法适合于快速定位记录;GROUP BY方法可用于统计重复记录的数量;而DISTINCT方法适用于...

    查询和删除表中重复数据

    本文介绍了查询和删除表中重复数据的几种常用方法。对于查询部分,我们可以通过 `ROWID`、`GROUP BY` 和 `DISTINCT` 来实现;对于删除部分,可以基于单个字段或者多个字段的组合来进行。这些方法适用于不同的数据库...

    oracle面试题集锦

    本文将从多个方面对 oracle 的知识点进行总结,包括查找部门的前 2 名、事务概念、触发器的作用、实现索引的方式、view 的概念、 truncate 和 delete 的区别、数据库启动与关闭的步骤、删除重复记录、授予权限等。...

    oracle约束和索引笔记

    它们分为以下几种类型: - **非空约束(NOT NULL)**: 非空约束不允许字段值为NULL,确保该字段始终有值。 - **唯一约束(UNIQUE)**: 这种约束保证字段中的每个值都是唯一的,但允许NULL值。可以应用于单个字段...

    Oracle20060626.docx

    本文将详细介绍几种在Oracle数据库中快速删除重复记录的方法及其各自的优缺点。 ##### 1. 创建临时表 **方法概述:** 该方法首先创建一个临时表,将原始表中的唯一记录插入临时表中,然后清空原始表,并将临时表...

    指导学习oracle

    在Oracle数据库中处理重复记录是常见的需求之一。 ##### 查找重复记录 使用以下SQL语句可以查找具有重复 `id` 的记录: ```sql SELECT id, COUNT(*) FROM dumpy GROUP BY id HAVING COUNT(*) &gt; 1; ``` 或者更...

    oracle常用的数据库脚本

    在Oracle数据库管理中,脚本是执行特定任务的SQL或PL/SQL集合,它们极大地提高了DBA(数据库管理...在实际工作中,结合《oracle去除重复记录的方法.docx》文档中的详细步骤和示例,将有助于进一步理解和应用这些概念。

    Oracle——sql语句优化

    UNION操作符虽然方便,但会在结果集中自动去除重复记录,这意味着需要额外的排序和去重步骤,这在大数据量的情况下可能引发性能瓶颈。 **推荐方案**:使用UNION ALL替代UNION,以避免不必要的排序和去重操作,从而...

    Dave Oracle 學習手册_v1.2

    - **快速查找**:通过索引可以快速定位到表中的记录,提高查询速度。 - **唯一性**:可以创建唯一索引来保证表中某列的值是唯一的。 - **覆盖索引**:如果查询的字段都在索引中,则可以直接从索引中获取数据,无需...

    ORACLE基本操作

    Oracle 提供了几种方法来删除表中的重复记录。 **查找重复记录**: ```sql SELECT * FROM 表 WHERE Id IN (SELECT Id FROM 表 GROUP BY Id HAVING COUNT(Id) &gt; 1); ``` - **用途**:找出重复的记录。 **删除重复...

    oracle优化

    可以通过以下几种方式减少访问数据库的次数: - 整合简单的数据库查询。 - 使用存储过程或者批处理来执行多个操作。 - 缓存频繁使用的查询结果。 #### 五、调整ARRAYSIZE参数 在SQL*Plus、SQL*Forms和Pro*C中,...

    ORACLEEBS_FORM

    - **Oracle 死锁之解决方法**:提供了几种解决Oracle死锁问题的策略。 - **PL/SQL 过程调用表示法**:介绍了如何在PL/SQL中调用过程。 - **PL/SQL 调用 Java 类**:如何在PL/SQL环境中调用Java代码。 - **PL/SQL...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    oracle 甲骨文 获得最高认证级别的ISO标准安全认证,性能最高, 保持开放平台下的TPC-D和TPC-C的世界记录。但价格不菲 大型企业 db2 IBM DB2在企业级的应用最为广泛, 在全球的500家最大的企业中,几乎85%以上用DB2...

    探讨煤炭企业中ORACLE数据库的应用.pdf

    使用DELETE命令删除重复数据,根据数据量大小选择IN子句或SELECT子句以提高删除速度;在查找不同数据记录时,通过NOT EXISTS子句来提高查找效率。\n\n2. **数据管理与安全性**\n ORACLE数据库提供了一致性和完整性...

    Oracle经典问题

    虽然题目要求删除重复记录但保留一条,但由于题目没有给出具体的删除逻辑,这里只给出了查询重复记录的SQL语句。实际操作中,可以通过其他方式(如使用`ROW_NUMBER()`函数)来确定哪些记录应该被保留或删除。 以上...

    Oracle 常用函数110种详解

    在Oracle数据库中,掌握各种函数的使用方法对于进行数据处理和分析至关重要。以下是从给定的部分内容中提取并详细解释的几个重要函数。 #### 1. ASCII 该函数用于返回与指定字符相对应的十进制数字值。 ```sql SQL&gt;...

    ORACLE数据库及SQL语言考试题一(含答案).docx

    - **定义**:数据库是一种系统化的数据存储方式,它按照一定的数据结构组织、存储和管理数据,以便能够有效地查找和管理这些数据。 - **特点**: - 提供了高效的数据访问手段。 - 支持数据的一致性和完整性控制。 ...

    Oracle SQL性能优化

    `TRUNCATE`和`DELETE`都可以用来删除表中的数据,但是两者之间存在一些关键区别:`TRUNCATE`不记录任何日志,执行速度较快;而`DELETE`则会记录日志,支持回滚。在删除大量数据时,`TRUNCATE`是一个更好的选择,但...

Global site tag (gtag.js) - Google Analytics