删除Oracle SQL中的重复项

时间:2015-09-04 13:53:39

标签: oracle oracle10g

目前,我使用的是没有主键的表。因此,在加载表时,可能会加载重复项。

我使用自动进程加载表,并且该进程中的删除脚本会从表中删除dubplicates。但是,不重复的记录也会被删除。我无法弄清楚原因。请提供您的意见。

表名:员工

在删除脚本运行之前加载后的表

EmpID   SalID   EmpName   EmpAddr     EmpZip    
 112     012     Smith      TN        641604    
 112     012     Smith      TN        641604    
 113     013     Steve      KA        560068    
 114     014     Rao        KA        560069    
 115     015     Ram        KA        560100    
 115     015     Ram        KA        560100    

删除脚本运行后的表

EmpID   SalID   EmpName   EmpAddr     EmpZip    
 112     012     Smith      TN        641604    
 114     014     Rao        KA        560069    
 115     015     Ram        KA        560100    

奇怪的是,EmpId 113被删除,而EmpId 114被保留。

以下是删除脚本

DELETE FROM EMPLOYEE E1 WHERE EXISTS
(SELECT 1 FROM EMPLOYEE E2 WHERE E2.EMPID = E1.EMPID 
AND E2.SALID = E1.SALID AND E2.EMPNAME = E1.EMPNAME
AND E2.EMPADDR = E1.EMPADDR AND E2.EMPZIP = E1.EMPZIP
AND E2.ROWID > E1.ROWID)

请注意你的错误。

4 个答案:

答案 0 :(得分:0)

Rowid =类似的东西:AAAIVuAABAAAMhCAAA

“大于”工作,但不像预期的那样,它不是像“rownum”那样的数值。

您应尝试使用“E2.ROWID<> E1.ROWID”而不是“E2.ROWID> E1.ROWID”,这是清理重复项的常用方法。

答案 1 :(得分:0)

我怀疑你的真实数据不是你的例子。

使用Rowid是一种奇怪的过滤方式。我猜你想要最后一个?在这种情况下,rowid 可能是最新的,但这一切都取决于它的加载方式,并不一定是该行的最佳指标。如果你只是从这个数据开始工作,你甚至关心rowid吗?

这就是我得到的:

Create table emp1 (EmpID varchar(20),  SalID   varchar(20),EmpName   varchar(20),EmpAddr     varchar(20),EmpZip  varchar(20));
insert into emp1 values ('112',     '012',     'Smith',      'TN',        '641604');    
insert into emp1 values ('112',     '012',     'Smith',      'TN',        '641604'); 
insert into emp1 values ('113',     '013',     'Steve',      'KA',        '560068') ;
insert into emp1 values ('114',     '014',     'Rao',      'KA',        '560069') ;
insert into emp1 values ('115',     '015',     'Ram',      'KA',        '560100') ;
insert into emp1 values ('115',     '015',     'Ram',      'KA',        '560100') ;


DELETE FROM EMP1 E1 WHERE EXISTS
(SELECT 1 FROM EMP1 E2 WHERE E2.EMPID = E1.EMPID 
AND E2.SALID = E1.SALID AND E2.EMPNAME = E1.EMPNAME
AND E2.EMPADDR = E1.EMPADDR AND E2.EMPZIP = E1.EMPZIP
AND E2.ROWID > E1.ROWID);


select * from emp1;
112 012 Smith   TN  641604
113 013 Steve   KA  560068
114 014 Rao KA  560069
115 015 Ram KA  560100

http://sqlfiddle.com/#!4/e2190/2/0

答案 2 :(得分:0)

只要您没有任何其他标识符,使用rowid来区分重复的条目是完全可以接受的方法。

SQL> select * from emp1
  2  /

EMPID    SALID    EMPNAME  EMPADDR  EMPZIP
-------- -------- -------- -------- ------
112      012      Smith    TN       641604
112      012      Smith    TN       641604
113      013      Steve    KA       560068
114      014      Rao      KA       560069
115      015      Ram      KA       560100
115      015      Ram      KA       560100

6 rows selected.

Elapsed: 00:00:00.00
SQL> delete from emp1
  2  where rowid not in (
  3      select min(rowid)
  4      from emp1
  5      group by EmpID, SalID,EmpName,EmpAddr,EmpZip
  6  )
  7  /

2 rows deleted.

Elapsed: 00:00:00.00
SQL> select * from emp1
  2  /

EMPID    SALID    EMPNAME  EMPADDR  EMPZIP
-------- -------- -------- -------- ------
112      012      Smith    TN       641604
113      013      Steve    KA       560068
114      014      Rao      KA       560069
115      015      Ram      KA       560100

Elapsed: 00:00:00.00

答案 3 :(得分:0)

当行的顺序不重要时。

arrangeComplete

或者当订单很重要时。

DELETE FROM 
   emp1 A
WHERE 
  a.rowid > ANY (SELECT B.rowid FROM emp1 B WHERE a.EmpID = b.EmpId and a.SalID = b.SalID and  a.EmpName = b.EmpName);