`

用Oracle的分析函数删除重复的数据

阅读更多

用Oracle的分析函数删除重复的数据

没有主键(Primary Key)约束保护的表格可能会让重复的数据行被插入进来。查找这种重复数据的传统方式是通过GROUP BY和HAVING关键字进行查询。在根据关键列把数据分组并计算每个组里的行数之后,有一个以上成员的组就是带有重复数据的组。

 

     尽管发现这样的数据行很容易,但是解决这一问题却十分耗时。在Oracle里,独特的ROWID伪列(pseudocolumn)意味着没有两个列是真正一模一样的。你可以总是利用删除(DELETE)查询来参考一个以外的所有ROWID,以便删除所有的重复数据。这非常有效——如果你没有太多的重复数据需要删除的话。而Oracle 9i里引入的分析函数给予了我们一种更简单的方式来进行这种清除工作。

  ROW_NUMBER()分析函数与ROWNUM伪列相似的地方在于它们都能够给输出的行编号。但是ROWNUM给出的是整个数据列完整的序列,而ROW_NUMBER会在我们在数据列里定义的每个分区里把编号重新设置回1。这样做的结果是不仅能够很容易就看到哪个组里有多个成员,还能够确切知道需要删除哪个行。

  分析查询的格式是:

  Functionname (arguments) OVER (PARTITION BY columns ORDER BY columns)

  现在让我们假设在创建SCOTT.EMP表格副本的时候出现了错误,所有的行都被输入了两遍。尝试加入一个主键约束会失败,因为数据已经出现了重复。列表A显示了这一过程,为了清楚说明问题,它被分成两个阶段:

  Listing A SQL> -- Will you just LOOK at this table? Lots of duplicates!

  SQL>

  SQL> SELECT empno, ename

  FROM emp2

  ORDER BY empno;

 

  EMPNO ENAME

  ---------- ----------

  7369 SMITH

  7369 SMITH

  7499 ALLEN

  7499 ALLEN

  7521 WARD

  7521 WARD

  7566 JONES

  7566 JONES

  7654 MARTIN

  7654 MARTIN

  7698 BLAKE

  7698 BLAKE

  7782 CLARK

  7782 CLARK

  7788 SCOTT

  7788 SCOTT

  7839 KING

  7839 KING

  7844 TURNER

  7844 TURNER

  7876 ADAMS

  7876 ADAMS

  7900 JAMES

  7900 JAMES

  7902 FORD

  7902 FORD

  7934 MILLER

  7934 MILLER

  28 rows selected.

  SQL> -- First step: number the duplicates of each empno

  SQL>

  SQL> SELECT ROWID, ROW_NUMBER() OVER (PARTITION BY empno ORDER BY empno) rn

  FROM emp2;

 

  ROWID RN

  ------------------ ----------

  AAAM1UAAEAAAAGsAAA 1

  AAAM1UAAEAAAAGuAAA 2

  AAAM1UAAEAAAAGuAAB 1

  AAAM1UAAEAAAAGsAAB 2

  AAAM1UAAEAAAAGsAAC 1

  AAAM1UAAEAAAAGuAAC 2

  AAAM1UAAEAAAAGuAAD 1

  AAAM1UAAEAAAAGsAAD 2

  AAAM1UAAEAAAAGsAAE 1

  AAAM1UAAEAAAAGuAAE 2

  AAAM1UAAEAAAAGsAAF 1

  AAAM1UAAEAAAAGuAAF 2

  AAAM1UAAEAAAAGsAAG 1

  AAAM1UAAEAAAAGuAAG 2

  AAAM1UAAEAAAAGsAAH 1

  AAAM1UAAEAAAAGuAAH 2

  AAAM1UAAEAAAAGsAAI 1

  AAAM1UAAEAAAAGuAAI 2

  AAAM1UAAEAAAAGsAAJ 1

  AAAM1UAAEAAAAGuAAJ 2

  AAAM1UAAEAAAAGsAAK 1

  AAAM1UAAEAAAAGuAAK 2

  AAAM1UAAEAAAAGsAAL 1

  AAAM1UAAEAAAAGuAAL 2

  AAAM1UAAEAAAAGsAAM 1

  AAAM1UAAEAAAAGuAAM 2

  AAAM1UAAEAAAAGuAAN 1

  AAAM1UAAEAAAAGsAAN 2

  28 rows selected.

  SQL> -- Now, use that as an inline view, and select just the dups

  SQL> -- We're including the row number, it won't be in the final query

  SQL>

  SQL> SELECT ROWID, rn

  FROM

  (SELECT ROWID, ROW_NUMBER() OVER (PARTITION BY empno ORDER BY empno) rn

  FROM emp2)

  WHERE rn > 1;

 

  ROWID RN

  ------------------ ----------

  AAAM1UAAEAAAAGuAAA 2

  AAAM1UAAEAAAAGsAAB 2

  AAAM1UAAEAAAAGuAAC 2

  AAAM1UAAEAAAAGsAAD 2

  AAAM1UAAEAAAAGuAAE 2

  AAAM1UAAEAAAAGuAAF 2

  AAAM1UAAEAAAAGuAAG 2

  AAAM1UAAEAAAAGuAAH 2

  AAAM1UAAEAAAAGuAAI 2

  AAAM1UAAEAAAAGuAAJ 2

  AAAM1UAAEAAAAGuAAK 2

  AAAM1UAAEAAAAGuAAL 2

  AAAM1UAAEAAAAGuAAM 2

  AAAM1UAAEAAAAGsAAN 2

  14 rows selected.

  SQL> -- Now we DELETE all the rows in that set

  SQL>

  SQL> DELETE FROM emp2

  WHERE ROWID IN

  (SELECT ROWID

  FROM (SELECT ROWID,

  ROW_NUMBER() OVER (PARTITION BY empno ORDER BY EMPNO) rn

  FROM emp2)

  WHERE rn > 1);

 

  14 rows deleted.

  SQL> commit;

  Commit complete.

  SQL> -- Show the de-dup'ed table

  SQL>

  SQL> SELECT empno, ename

  FROM emp2;

 

  EMPNO ENAME

  ---------- ----------

  7369 SMITH

  7521 WARD

  7654 MARTIN

  7698 BLAKE

  7782 CLARK

  7788 SCOTT

  7839 KING

  7844 TURNER

  7876 ADAMS

  7900 JAMES

  7902 FORD

  7499 ALLEN

  7566 JONES

  7934 MILLER

  首先是一个分析查询,通过empno行来分区;它使用ROW_NUMBER()给每个分区进行编号。如果没有重复的内容,分区就只有一个行,编号是“1”。但是,如果存在重复,那么它们就会被编上2、3等号码。这个查询还会返回我们用来唯一识别数据行的ROWID。第一个查询然后就被用作另外一个查询的内联视图,这第二个查询使用一个WHERE子句过滤掉“1”行,只返回重复的内容。最后,一个DELETE语句通过第二个查询使用IN操作符来删掉所有的重复内容。

  就和所有的大规模DELETE一样,你需要记住的是,最好把想要保留的行(也就是说那些ROW_NUMBER为1的行)保存到一个新的表格里。INSERT所造成的负载要比DELETE小得多。

分享到:
评论

相关推荐

    Oracle数据库学习指南

    30.删除表内重复记录的方法 31.数据库安全性策略 32.数据库的查询优化技术. 33.提高C-S系统性能的一些方法 34.提高ORACLE数据库系统import性能 35.外部联接的用法 36.性能调试的一般问题 37.优化 38...

    oracle的sql优化

    oracle的sql优化方法 1.全表扫描和索引扫描  大数据量表尽量要避免全表扫描,全部扫描会按顺序每条记录扫描,... *尽量使用表关联查询而不使用函数,但涉及类似于代码表要重复关联多次取数据问题时候又适合使用函数

    ORACLE数据库智能化管理系统2012

    重复数据可自动处理成唯一,也可自行处理;可自定义选择从查询结果集中的数行,进行数据求合及自定义图形项目分析;字段的10多种属性设置;数据窗口自创帮你省去建表才能进行数据处理的麻烦;各行数据在总数据所占的...

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

    其三、职业方向多:Oracle数据库管理方向、Oracle开发及系统架构方向、Oracle数据建模数据仓库等方向。 四、 如何学习 认真听课、多思考问题、多动手操作、有问题一定要问、多参与讨论、多帮组同学 五、 体系结构 ...

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    作者通过总结各自多年的软件开发和教学培训经验,与大家分享了掌握Oracle SQL所独有的丰富功能的技巧所在,内容涵盖SQL执行、联结、集合、分析函数、子句、事务处理等多个方面。读者可以学习到以下几个方面的技巧:...

    ORACLE9i_优化设计与系统调整

    §13.2.1 使用函数索引 165 §13.2.2 使用位图索引- 166 §13.2.3 使用B树索引- 166 §13.2.4 使用反向键索引- 166 §13.2.5 使用索引组织表 166 §13.3 使用范围索引 166 §13.4 使用簇 - 167 §13.5 使用Hash 簇 -...

    最全的oracle常用命令大全.txt

    下面按类别列出一些ORACLE用户常用数据字典的查询使用方法。 1、用户 查看当前用户的缺省表空间 SQL>select username,default_tablespace from user_users; 查看当前用户的角色 SQL>select * from user_...

    Oracl技术资料(EBook)

    30.删除表内重复记录的方法 31.数据库安全性策略 32.数据库的查询优化技术. 33.提高C-S系统性能的一些方法 34.提高ORACLE数据库系统import性能 35.外部联接的用法 36.性能调试的一般问题 37.优化 38.优化...

    精通SQL 结构化查询语言详解

    5.2.3 使用DISTINCT去除重复信息  5.2.4 多列查询  5.2.5 查询所有的列 5.3 排序查询结果 5.3.1 单列排序  5.3.2 多列排序 5.3.3 采用序号进行多列排序 5.3.4 反向排序  5.4 使用WHERE子句定义搜索条件...

    Oracle9i的init.ora参数中文说明

    说明: 指定与 TO_CHAR 和 TO_DATE 函数一同使用的默认日期格式。该参数的默认值由 NLS_TERRITORY 确定。该参数的值可以是包含在双引号内的任何有效的日期格式掩码。例如: ''MMM/DD/YYYY''。 值范围: 任何有效的日期...

    精通SQL--结构化查询语言详解

    5.2.3 使用distinct去除重复信息 86 5.2.4 多列查询 87 5.2.5 查询所有的列 88 5.3 排序查询结果 89 5.3.1 单列排序 89 5.3.2 多列排序 90 5.3.3 采用序号进行多列排序 91 5.3.4 反向排序 92 5.4 使用where...

    PLSQL程序优化和性能分析方法

    2.4.16 删除重复记录 14 2.4.17 COMMIT使用 15 2.4.18 减少多表关联 15 2.4.19 批量数据插入 15 2.5 索引使用优化 16 2.5.1 避免在索引列上使用函数或运算 16 2.5.2 避免改变索引列的类型. 17 2.5.3 避免在索引列上...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例112 解决用substr()函数对中文字符串截取时出现乱码的问题 143 实例113 字符串与HTML标记相互转换 144 实例114 运用PHP 5.0新型字符串输出XML数据 145 实例115 判断字符串中是否存在指定子串 146 2.9 正则表达式...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例112 解决用substr()函数对中文字符串截取时出现乱码的问题 143 实例113 字符串与HTML标记相互转换 144 实例114 运用PHP 5.0新型字符串输出XML数据 145 实例115 判断字符串中是否存在指定子串 146 2.9 正则表达式...

    程序员的SQL金典.rar

    透彻分析函数、子查询、表连接、不同DBMS中的SQL语法差异、SQL调优、NULL值处理、事务、开窗函数等高级技术;通过对实际案例开发过程的详细分析,使读者掌握 SQL的综合应用技巧。 内容简介 本书主要介绍SQL的语法...

    程序员的SQL金典6-8

     4.5 抑制数据重复  4.6 计算字段  4.6.1 常量字段  4.6.2 字段间的计算  4.6.3 数据处理函数  4.6.4 字符串的拼接  4.6.5 计算字段的其他用途  4.7 不从实体表中取的数据  4.8 联合结果集  4.8.1 简单的...

    程序员的SQL金典7-8

     4.5 抑制数据重复  4.6 计算字段  4.6.1 常量字段  4.6.2 字段间的计算  4.6.3 数据处理函数  4.6.4 字符串的拼接  4.6.5 计算字段的其他用途  4.7 不从实体表中取的数据  4.8 联合结果集  4.8.1 简单的...

    orcale常用命令

    下面按类别列出一些ORACLE用户常用数据字典的查询使用方法。 1、用户 查看当前用户的缺省表空间 SQL>select username,default_tablespace from user_users; 查看当前用户的角色 SQL>select * from user_...

Global site tag (gtag.js) - Google Analytics