- 浏览: 387450 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
Nabulio:
写的详细,特殊语法学习到了
jdk1.5-1.9新特性 -
wooddawn:
您好,最近在做个足球数据库系统,用到了betbrain的数据表 ...
javascript深入理解js闭包 -
lwpan:
很受启发 update也可以
mysql 的delete from 子查询限制 -
wuliaolll:
不错,总算找到原因了
mysql 的delete from 子查询限制
平时工作中可能会遇到当试图对库表中的某一列或几列创建唯一索引时,系统提示 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.
从结果里可以看到重复记录已经删除。
下面总结一下几种查找和删除重复记录的方法(以表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.
从结果里可以看到重复记录已经删除。
发表评论
-
mysql在第一次查询的时候很慢,第二次查询就比较快的原因?
2014-10-09 09:53 27121、默认 query_cache 是打开的 你使用 sh ... -
mysql sql_safe_updates 分析
2014-08-06 17:41 822排名前5的SQL悲剧中肯定有: delete fro ... -
mysql or条件可以使用索引而避免全表
2014-06-16 09:15 499在某些情况下,or条件可以避免全表扫描的。 1 . ... -
mysql 的delete from 子查询限制
2014-01-15 15:29 157851.使用mysql进行delete from操作时,若子查询 ... -
MySQL 5.6的72个新特性
2013-08-12 17:24 928一,安全提高 1.提供保存加密认证信息的方法,使用.myl ... -
mysql交换一个表中的两列值
2013-07-19 18:49 1353mysql交换一个表中的两列值 update tabl ... -
mySQL事务设置,以及SQLyog中的设置
2013-07-04 17:19 46211. 即使在创建Mysql时url ... -
MySQL中当记录更新时 timestamp类型自动更新时间
2013-06-25 10:52 999做项目需要用到这个特性。 我使用navica ... -
mysql隔离级别是怎么实现的?
2013-03-13 08:13 908有待思考和探索,mysql的隔离级别是怎样实现的? ... -
mysql跨表删除
2013-03-08 14:36 832前几天写了Mysql跨表更新的一篇总结,今天我们看下跨表删除。 ... -
oracle 创建表空间,用户,授权
2013-01-14 10:57 8201.创建表空间 SQL> create tablespa ... -
having count 删除重复数据只保留一条
2012-12-14 11:56 1093用SQL语句,删除掉重复项只保留一条 在几千条记录里,存在着 ... -
数据库设计14个技巧
2012-11-28 10:53 8031. 原始单据与实体之间 ... -
数据建模
2012-11-23 09:02 1094建模过程中的主要活动包括: 确定数据及其相关过程(如实地销 ... -
database questions
2012-10-22 20:08 9351.Explain inner and outer joins ... -
数据库基础(面试常见题)
2012-10-15 09:36 858http://blog.csdn.net/maomao0920 ... -
数据库面试题集1
2012-10-15 09:34 1281阿里巴巴公司DBA笔试题 ...
相关推荐
### Oracle中用Rowid查找和删除表中的重复记录 在Oracle数据库管理中,处理重复记录是一项常见的需求,尤其是在数据量较大的情况下。本文将详细介绍如何利用Rowid这一特性来有效地查找和删除表中的重复记录。 ####...
以上几种方法都可以有效地帮助我们查找和删除Oracle数据库中的重复记录。选择哪种方法取决于具体的业务需求和数据规模。ROWID方法适合于快速定位记录;GROUP BY方法可用于统计重复记录的数量;而DISTINCT方法适用于...
本文介绍了查询和删除表中重复数据的几种常用方法。对于查询部分,我们可以通过 `ROWID`、`GROUP BY` 和 `DISTINCT` 来实现;对于删除部分,可以基于单个字段或者多个字段的组合来进行。这些方法适用于不同的数据库...
本文将从多个方面对 oracle 的知识点进行总结,包括查找部门的前 2 名、事务概念、触发器的作用、实现索引的方式、view 的概念、 truncate 和 delete 的区别、数据库启动与关闭的步骤、删除重复记录、授予权限等。...
它们分为以下几种类型: - **非空约束(NOT NULL)**: 非空约束不允许字段值为NULL,确保该字段始终有值。 - **唯一约束(UNIQUE)**: 这种约束保证字段中的每个值都是唯一的,但允许NULL值。可以应用于单个字段...
本文将详细介绍几种在Oracle数据库中快速删除重复记录的方法及其各自的优缺点。 ##### 1. 创建临时表 **方法概述:** 该方法首先创建一个临时表,将原始表中的唯一记录插入临时表中,然后清空原始表,并将临时表...
在Oracle数据库中处理重复记录是常见的需求之一。 ##### 查找重复记录 使用以下SQL语句可以查找具有重复 `id` 的记录: ```sql SELECT id, COUNT(*) FROM dumpy GROUP BY id HAVING COUNT(*) > 1; ``` 或者更...
在Oracle数据库管理中,脚本是执行特定任务的SQL或PL/SQL集合,它们极大地提高了DBA(数据库管理...在实际工作中,结合《oracle去除重复记录的方法.docx》文档中的详细步骤和示例,将有助于进一步理解和应用这些概念。
UNION操作符虽然方便,但会在结果集中自动去除重复记录,这意味着需要额外的排序和去重步骤,这在大数据量的情况下可能引发性能瓶颈。 **推荐方案**:使用UNION ALL替代UNION,以避免不必要的排序和去重操作,从而...
- **快速查找**:通过索引可以快速定位到表中的记录,提高查询速度。 - **唯一性**:可以创建唯一索引来保证表中某列的值是唯一的。 - **覆盖索引**:如果查询的字段都在索引中,则可以直接从索引中获取数据,无需...
Oracle 提供了几种方法来删除表中的重复记录。 **查找重复记录**: ```sql SELECT * FROM 表 WHERE Id IN (SELECT Id FROM 表 GROUP BY Id HAVING COUNT(Id) > 1); ``` - **用途**:找出重复的记录。 **删除重复...
可以通过以下几种方式减少访问数据库的次数: - 整合简单的数据库查询。 - 使用存储过程或者批处理来执行多个操作。 - 缓存频繁使用的查询结果。 #### 五、调整ARRAYSIZE参数 在SQL*Plus、SQL*Forms和Pro*C中,...
- **Oracle 死锁之解决方法**:提供了几种解决Oracle死锁问题的策略。 - **PL/SQL 过程调用表示法**:介绍了如何在PL/SQL中调用过程。 - **PL/SQL 调用 Java 类**:如何在PL/SQL环境中调用Java代码。 - **PL/SQL...
oracle 甲骨文 获得最高认证级别的ISO标准安全认证,性能最高, 保持开放平台下的TPC-D和TPC-C的世界记录。但价格不菲 大型企业 db2 IBM DB2在企业级的应用最为广泛, 在全球的500家最大的企业中,几乎85%以上用DB2...
使用DELETE命令删除重复数据,根据数据量大小选择IN子句或SELECT子句以提高删除速度;在查找不同数据记录时,通过NOT EXISTS子句来提高查找效率。\n\n2. **数据管理与安全性**\n ORACLE数据库提供了一致性和完整性...
虽然题目要求删除重复记录但保留一条,但由于题目没有给出具体的删除逻辑,这里只给出了查询重复记录的SQL语句。实际操作中,可以通过其他方式(如使用`ROW_NUMBER()`函数)来确定哪些记录应该被保留或删除。 以上...
在Oracle数据库中,掌握各种函数的使用方法对于进行数据处理和分析至关重要。以下是从给定的部分内容中提取并详细解释的几个重要函数。 #### 1. ASCII 该函数用于返回与指定字符相对应的十进制数字值。 ```sql SQL>...
- **定义**:数据库是一种系统化的数据存储方式,它按照一定的数据结构组织、存储和管理数据,以便能够有效地查找和管理这些数据。 - **特点**: - 提供了高效的数据访问手段。 - 支持数据的一致性和完整性控制。 ...
`TRUNCATE`和`DELETE`都可以用来删除表中的数据,但是两者之间存在一些关键区别:`TRUNCATE`不记录任何日志,执行速度较快;而`DELETE`则会记录日志,支持回滚。在删除大量数据时,`TRUNCATE`是一个更好的选择,但...