从Oracle中删除表中的重复行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Oracle中删除表中的重复行相关的知识,希望对你有一定的参考价值。

我正在Oracle中测试一些东西,并用一些示例数据填充了一个表,但是在这个过程中我不小心加载了重复的记录,所以现在我无法使用某些列创建主键。

如何删除所有重复的行并只留下其中一行?

答案

使用rowid伪列。

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

column1column2column3构成每条记录的识别密钥。您可以列出所有列。

另一答案

Solution 4)

 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
);
另一答案

解决方案

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

解决方案

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 ); 

解决方案

 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.解决方案

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
    );
另一答案
DELETE from table_name where rowid not in (select min(rowid) FROM table_name group by column_name);

您还可以用其他方式删除重复记录

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
另一答案
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. 创建具有以下结构的异常表:exceptions_table ROW_ID ROWID OWNER VARCHAR2(30) TABLE_NAME VARCHAR2(30) CONSTRAINT VARCHAR2(30)
  2. 尝试创建一个唯一的约束或主键,重复项将违反。您将收到错误消息,因为您有重复项。例外表将包含重复行的rowid。 alter table add constraint unique --or primary key (dupfield1,dupfield2) exceptions into exceptions_table;
  3. 通过rowid加入您的表和exceptions_table并删除dups delete original_dups where rowid in (select ROW_ID from exceptions_table);
  4. 如果要删除的行数很大,则创建一个新表(包含所有授权和索引),使用rowid反例例连接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 ) )
另一答案

检查下面的脚本 -

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条记录。 4.run以下查询 -

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;

您将看到已删除重复记录。 希望这能解决您的疑问。谢谢 :)

另一答案

我没有看到任何使用公用表表达式和窗口函数的答案。这是我最容易使用的。

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
               SUM(1)
               OVER(
               PARTITION BY First_Name, Last_Name, Birth_Date
               ORDER BY ROWID ROWS BETWEEN UNBOUNDED PRECEDING 
                                       AND UNBOUNDED FOLLOWING)
                   AS CNT
              FROM
               YourTable
              WHERE
               Load_Date IS NULL)
     SELECT
      RID
     FROM
      duplicates
     WHERE
      RN > 1);

有些事要注意:

1)我们只检查partition子句中字段的重复。

2)如果您有某种理由选择一个副本而不是其他副本,您可以使用order by子句使该行具有row_number()= 1

3)您可以通过将最终where子句更改为“Where RN> N”来更改保留的数字,其中N> = 1(我认为N = 0将删除所有具有重复项的行,但它只会删除所有行) 。

4)在CTE查询中添加了Sum分区字段,该查询将使用组中的数字行标记每一行。因此,要选择具有重复项的行,包括第一项使用“WHERE cnt> 1”。

另一答案

来自Ask Tom

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);

(修正了缺失的括号)

另一答案
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 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 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
);
另一答案

来自DevX.com

DEL

以上是关于从Oracle中删除表中的重复行的主要内容,如果未能解决你的问题,请参考以下文章

oracle之如何删除表中的重复记录只保留其中一条

如何从 SQL Server 中的表中删除重复行 [重复]

在Oracle中从表中删除重复行

Oracle中如何删除重复数据

如何从 DbVisualizer 中删除表中的重复行

从同一查询中的两个表中删除 NULL 行[重复]