用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中删除表中的重复数据,可以采用多种策略,但通常涉及创建一个临时表来保存去重后的数据,然后用这个临时表覆盖原始表。这种方法可以避免直接修改原表带来的风险,确保操作的安全性。以下是一种具体的实现...
除了上述方法之外,还可以使用窗口函数`ROW_NUMBER()`来去除重复数据。这种方法在较新的Oracle版本中更为常用,其语法更简洁、易读。 ##### SQL语句示例 ```sql WITH cte AS ( SELECT *, ROW_NUMBER() OVER ...
使用分析函数也是一种删除重复数据的方法。这种方法可以使用 row_number() 函数来删除重复数据。 示例代码: ``` create table test_temp as select id,name,age from ( select row_number()over(partition by ...
在Oracle数据库中,查询重复数据主要依赖于SQL的聚合函数和子查询。具体来说,通过使用`GROUP BY`子句结合`COUNT()`函数,可以统计每个唯一标识符(如`peopleid`)出现的次数,再利用`HAVING`子句筛选出出现次数大于...
Oracle分析函数是数据库查询中的强大工具,它允许用户在数据集上执行复杂的分析操作,而不仅仅是简单的聚合。分析函数的特点在于它们能够对数据进行排序、筛选,并且可以在不同的分区、窗口和排序规则下运行,这使得...
### Oracle删除重复记录性能分析 #### 一、背景与需求 在数据库管理中,经常会遇到数据清理的需求,尤其是在Oracle数据库中处理重复记录时。本文旨在通过对比几种不同的方法来删除Oracle中的重复记录,并分析其...
本文将探讨三种不同的方法来高效地删除`demo`表中的重复数据,并分析它们的执行时间和适用场景。 方法一: 该方法基于ROWID进行操作,通过保留每个对象_ID中的最大ROWID(最新插入的记录),删除其他ROWID。SQL语句...
1. 如何识别重复数据:在Oracle中,可以使用窗口函数ROW_NUMBER()结合PARTITION BY子句来识别重复数据。这个函数可以为每个数据分区内的行生成一个唯一的序号。通过对重复数据感兴趣字段使用PARTITION BY子句,然后...
Oracle的分析函数row_number() over()是数据库查询中一种强大的工具,它用于对数据集进行分组和排序,尤其在处理重复数据或者实现排名时非常有用。在Oracle SQL中,row_number()函数会为每一行生成一个唯一的数字,...
接下来,我们讨论Oracle分析函数与聚合函数的区别。分析函数,如`LEAD()`, `LAG()`, `SUM() OVER()`, `AVG() OVER()`等,可以基于分组计算聚合值,同时返回多行结果。而聚合函数,如`AVG()`, `MAX()`, `MIN()`, `...
在日常的数据操作和分析中,掌握一些常用的Oracle函数和方法是至关重要的。以下是对"Oracle最常用的函数或方法总结"的详细阐述: 1. **字符串处理函数** - `CONCAT()`:用于连接两个或多个字符串。 - `SUBSTR()`...
在SQL查询中,我们可以直接使用这些函数来比较不同字符串间的相似程度,从而进行数据匹配、模糊搜索等操作。 Oracle提供了多个字符相似度函数,其中最常用的包括`SIMILARITY()`和`UTL_MATCH`包中的几个函数,如`...
这里我们将深入探讨在标题和描述中提到的Oracle函数类别:连续求和分析函数、排序函数、日期转换函数、数值型函数以及字符型函数。 1. **连续求和分析函数**: 分析函数在处理大量数据时非常有用,它们允许我们在...
`ROW_NUMBER()`函数是Oracle分析函数之一,它可以为每一行返回一个唯一的整数。这个函数通常与`OVER`子句一起使用,以便在指定的数据分组内进行排序。 #### 二、ROW_NUMBER() 去重示例 根据给定的内容,我们可以...
### Oracle分析函数详解:row_number() over 在Oracle数据库中,分析函数(Analytic Functions)是一种强大而灵活的数据处理工具,它们能够在查询结果集中对每一行数据进行计算,而不像传统的聚合函数那样只返回...
### 企业Oracle数据分析岗位面试题解析 #### 一、数据库系统的认知 - **知识点解析**: - **数据库系统概述**:数据库系统是指用于管理和处理数据的软件集合,包括数据库管理系统(DBMS)以及相关应用软件和服务...
Oracle数据库作为一个强大的关系型数据库管理系统,提供了多种高级操作函数来支持复杂的数据处理。以下是从标题、描述和部分内容中提取的Oracle高级操作函数的知识点。 ### 分支判断函数 #### DECODE函数 DECODE...
- **UNION ALL**: 类似于 UNION,但它不会去除重复行。因此,如果两个 SELECT 语句中有相同的记录,这些记录将会在结果集中出现多次。 ### 2. MINUS - **MINUS**: 该运算符用于返回第一个 SELECT 语句的结果集中不...
在Oracle数据库管理中,处理数据冗余是一项非常重要的工作,特别是在大数据量的环境中,重复记录不仅浪费存储空间,还可能导致数据分析结果出现偏差。本文将详细介绍如何在Oracle数据库中有效地删除表内的重复记录。...
Oracle数据库作为一款广泛使用的数据库管理系统,在进行数据处理与分析时提供了丰富的内置函数,这些函数可以极大地简化SQL查询的编写工作,并提高查询效率。本文将根据给定的内容对Oracle数据库中的一些重要SQL函数...