在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 CLAUSE
select的条件。
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 );
真正的大桌子最快的方式
-
用下面的结构创buildexception表:exceptions_table
ROW_ID ROWID OWNER VARCHAR2(30) TABLE_NAME VARCHAR2(30) CONSTRAINT VARCHAR2(30)
-
尝试创build一个唯一的约束或主键将被违反重复。 你会得到一个错误消息,因为你有重复。 exception表将包含重复行的rowid。
alter table add constraint unique --or primary key (dupfield1,dupfield2) exceptions into exceptions_table;
-
通过rowid和删除dups与exception_tablejoin您的表
delete original_dups where rowid in (select ROW_ID from exceptions_table);
-
如果要删除的行数很大,则创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)
-
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);