在Oracle中删除表中的重复行

我在Oracle中testing一些东西,并用一些示例数据填充表,但在这个过程中,我不小心加载了重复logging,所以现在我无法使用某些列创build主键。

我怎样才能删除所有重复的行,只留下其中一个?

使用rowid伪列。

 DELETE FROM your_table WHERE rowid not in (SELECT MIN(rowid) FROM your_table GROUP BY column1, column2, column3); 

列1,列2和列3组成每个logging的标识关键字。 你可能会列出你所有的列。

从问问汤姆

 delete from t where rowid IN ( select rid from (select rowid rid, row_number() over (partition by companyid, agentid, class , status, terminationdate order by rowid) rn from t) where rn <> 1); 

(修正了缺失的括号)

从DevX.com :

 DELETE FROM our_table WHERE rowid not in (SELECT MIN(rowid) FROM our_table GROUP BY column1, column2, column3...) ; 

其中column1,column2等是您要使用的密钥。

 DELETE FROM tablename a WHERE a.ROWID > ANY (SELECT b.ROWID FROM tablename b WHERE a.fieldname = b.fieldname AND a.fieldname2 = b.fieldname2) 

创build表t2作为select不同*从t1;

解决scheme1)

 delete from emp where rowid not in (select max(rowid) from emp group by empno); 

解决scheme2)

 delete from emp where rowid in ( select rid from ( select rowid rid, row_number() over(partition by empno order by empno) rn from emp ) where rn > 1 ); 

解决scheme3)

 delete from emp e1 where rowid not in (select max(rowid) from emp e2 where e1.empno = e2.empno ); 

要select重复项,只有查询格式可以是:

 SELECT GroupFunction(column1), GroupFunction(column2),..., COUNT(column1), column1, column2... FROM our_table GROUP BY column1, column2, column3... HAVING COUNT(column1) > 1 

所以正确的查询按照其他build议是:

 DELETE FROM tablename a WHERE a.ROWID > ANY (SELECT b.ROWID FROM tablename b WHERE a.fieldname = b.fieldname AND a.fieldname2 = b.fieldname2 AND ....so on.. to identify the duplicate rows....) 

此查询将保留数据库中最旧的logging,以符合在WHERE CLAUSEselect的条件。

Oracleauthentication合作伙伴(2008)

使用rowid-

 delete from emp where rowid not in (select max(rowid) from emp group by empno); 

使用自join –

 delete from emp e1 where rowid not in (select max(rowid) from emp e2 where e1.empno = e2.empno ); 

解决scheme4)

  delete from emp where rowid in ( select rid from ( select rowid rid, dense_rank() over(partition by empno order by rowid ) rn from emp ) where rn > 1 ); 

解决scheme

 delete from emp where rowid not in (select max(rowid) from emp group by empno); 

2. sloution

 delete from emp where rowid in ( select rid from ( select rowid rid, row_number() over(partition by empno order by empno) rn from emp ) where rn > 1 ); 

3.solution

 delete from emp e1 where rowid not in (select max(rowid) from emp e2 where e1.empno = e2.empno ); 

4.解决scheme

  delete from emp where rowid in ( select rid from ( select rowid rid, dense_rank() over(partition by empno order by rowid ) rn from emp ) where rn > 1 ); 

5.解决scheme

 delete from emp where rowid in ( select rid from ( select rowid rid,rank() over (partition by emp_id order by rowid)rn from emp ) where rn > 1 ); 

你应该使用循环游标做一个小的pl / sql块,并删除你不想保留的行。 例如:

 declare prev_var my_table.var1%TYPE; begin for t in (select var1 from my_table order by var 1) LOOP -- if previous var equal current var, delete the row, else keep on going. end loop; end; 
 create or replace procedure delete_duplicate_enq as cursor c1 is select * from enquiry; begin for z in c1 loop delete enquiry where enquiry.enquiryno = z.enquiryno and rowid > any (select rowid from enquiry where enquiry.enquiryno = z.enquiryno); end loop; end delete_duplicate_enq; 
 DELETE FROM tableName WHERE ROWID NOT IN (SELECT MIN (ROWID) FROM table GROUP BY columnname); 
 delete from dept where rowid in ( select rowid from dept minus select max(rowid) from dept group by DEPTNO, DNAME, LOC ); 

真正的大桌子最快的方式

  1. 用下面的结构创buildexception表:exceptions_table

     ROW_ID ROWID OWNER VARCHAR2(30) TABLE_NAME VARCHAR2(30) CONSTRAINT VARCHAR2(30) 
  2. 尝试创build一个唯一的约束或主键将被违反重复。 你会得到一个错误消息,因为你有重复。 exception表将包含重复行的rowid。

     alter table add constraint unique --or primary key (dupfield1,dupfield2) exceptions into exceptions_table; 
  3. 通过rowid和删除dups与exception_tablejoin您的表

     delete original_dups where rowid in (select ROW_ID from exceptions_table); 
  4. 如果要删除的行数很大,则创build一个新的表(具有所有的授予和索引),通过rowid反exception地与exceptions_table连接,并将原始表重命名为original_dups表,并将new_table_with_no_dups重命名为原始表

     create table new_table_with_no_dups AS ( select field1, field2 ........ from original_dups t1 where not exists ( select null from exceptions_table T2 where t1.rowid = t2.row_id ) ) 

为了获得最佳performance,这里是我写的:
(见执行计划)

 DELETE FROM your_table WHERE rowid IN (select t1.rowid from your_table t1 LEFT OUTER JOIN ( SELECT MIN(rowid) as rowid, column1,column2, column3 FROM your_table GROUP BY column1, column2, column3 ) co1 ON (t1.rowid = co1.rowid) WHERE co1.rowid IS NULL ); 
 DELETE from table_name where rowid not in (select min(rowid) FROM table_name group by column_name); 

也可以通过其他方式删除重复的logging

 DELETE from table_name a where rowid > (select min(rowid) FROM table_name b where a.column=b.column); 
 create table abcd(id number(10),name varchar2(20)) insert into abcd values(1,'abc') insert into abcd values(2,'pqr') insert into abcd values(3,'xyz') insert into abcd values(1,'abc') insert into abcd values(2,'pqr') insert into abcd values(3,'xyz') select * from abcd id Name 1 abc 2 pqr 3 xyz 1 abc 2 pqr 3 xyz Delete Duplicate record but keep Distinct Record in table DELETE FROM abcd a WHERE ROWID > (SELECT MIN(ROWID) FROM abcd b WHERE b.id=a.id ); run the above query 3 rows delete select * from abcd id Name 1 abc 2 pqr 3 xyz 

检查下面的脚本 –

1。

 Create table test(id int,sal int); 

2。

  insert into test values(1,100); insert into test values(1,100); insert into test values(2,200); insert into test values(2,200); insert into test values(3,300); insert into test values(3,300); commit; 

3。

  select * from test; 

你会在这里看到6条logging。
4.在下面查询 –

 delete from test where rowid in (select rowid from (select rowid, row_number() over (partition by id order by sal) dup from test) where dup > 1) 
  1. select * from test;

您将看到重复logging已被删除。
希望这可以解决您的查询。 谢谢 :)

我没有看到任何使用公共表格expression式和窗口函数的答案。 这是我觉得最简单的工作。

 DELETE FROM YourTable WHERE ROWID IN (WITH Duplicates AS (SELECT ROWID RID, ROW_NUMBER() OVER( PARTITION BY First_Name, Last_Name, Birth_Date) AS RN FROM YourTable WHERE Load_Date IS NULL) SELECT RID FROM duplicates WHERE RN > 1);