【问题标题】:Delete duplicate rows using Analytical functions使用分析函数删除重复行
【发布时间】:2013-03-06 12:48:37
【问题描述】:

我们可以使用分析函数删除重复的行吗?我的意思是在Oracle的Sql查询中使用row_number()rank或dense_rank()?

【问题讨论】:

  • 您的要求不是很清楚。尝试编写您想要使用的查询,并将其发布在此处(如果您收到任何错误消息,请附上),这样人们就会更好地了解您想要什么。
  • 这个问题的答案是:“是”。如果您可以按照 Mat 的建议解释您正在尝试做什么,也许有人会更有帮助并提供更详尽的解释。
  • 我正在尝试删除重复的行。我知道在 oracl 中使用 rowid 也是可能的。还有其他方法吗??
  • 如果没有比需要更大的资源密集型 sql 语句。您真的不想使用 rowid 的任何原因?
  • 我只是想知道这是否可以使用没有 rowid 的分析函数来完成!!

标签: sql oracle duplicates rows analytical


【解决方案1】:

您可以在对您来说应该是唯一的列分区上使用ROW_NUMBER(),例如:ROW_NUMBER() OVER (PARTITION BY COLUMN1, COLUMN2 ORDER BY COLUMN1)。每个行号 > 1 的结果都是重复的。

然后,您可以返回这些的 rowid 并删除它们。

【讨论】:

  • 我知道如何使用 rowid 删除。但是我正在寻找不使用 rowid 的解决方案
  • 您无法在一条语句中完成删除具有分析功能的行。您可以使用多个语句来执行此操作,将唯一行放在它自己的表中。而不是用这个唯一数据替换当前表。
【解决方案2】:

是的。但是使用聚合函数可以使它更简单一些

-- delete duplicates
delete from table t1
where t1.rowid not in (
   select min(t2.rowid)
   from table t2
   group by t2.col1, t2.col2, ...
)

fiddle

【讨论】:

  • 我相信我们不能使用别名或表名如t1.rownum 引用rownum,因为rownumORACLE 中的保留工作
  • @Aspirant - 谢谢。固定。
  • 我们无法使用 rownum 删除
  • @JebySebastian - 不再有 rownums!
  • :) @Egor,还有其他方法可以做到这一点吗??
【解决方案3】:

我们可以使用 Analytical Functions 或任何其他方式,例如 Aggregate Functions ,'DISTINCT` 来找出我们的表中是否有重复项

喜欢使用Analytical Functions

select col1,col2,col3 from (select tbl.*,rowid rid,row_number() over (partition by col1,col2,col3 order by col1) rnum
from tbl) where rnum>1;

但要删除它们,我们需要获取rnum>1ROWID

delete from tbl where rowid in 
(select rid from (select tbl.*,rowid rid,row_number() over (partition by col1,col2,col3 order by col1) rnum
  from tbl) where rnum>1)

否则我们可以简单地使用

 create new_table as select distinct * from old_table

【讨论】:

  • 我知道如何使用 rowid 删除。但是我正在寻找不使用 rowid 的解决方案。
  • 不使用 rowid 我不这么认为只是创建一个具有原始表不同值的虚拟表:)
  • 我只是想知道这是否可以使用没有 rowid 的分析函数来完成!!
【解决方案4】:

按照这些步骤删除重复记录而不使用 rowid,rownum 1. 创建表来存储原始表的不同值。

    create table newtable as select distinct * from tablename;
  1. 从原始表中删除记录。

     truncate table tablename;
    
  2. 将临时表值插入原始表中。

     insert into tablename select * from newtable; 
    

【讨论】:

    【解决方案5】:

    您可以使用此查询删除重复的行:

    DELETE FROM EMP
    WHERE ROWID IN
    (
    SELECT RID FROM
    (SELECT ROWID RID,ROW_NUMBER() OVER(PARTITION BY DEPTNO ORDER BY ROWID) R FROM EMP) 
    WHERE R>1
    );
    

    【讨论】:

    • 我怀疑这是否有帮助,甚至根本有效。为了说服我,请解释一下这段代码。
    【解决方案6】:

    假设我们要从 emp 表中删除重复的 sal:

    select * from (
      select 
        empno, 
        ename, 
        sal, 
        row_number() over (partition by sal order by sal asc) rw_number
      from emp)
    where rw_number = 1
    

    【讨论】:

      【解决方案7】:
      DELETE FROM emp 
      WHERE rowid IN
      (
          SELECT rid from
          (
              SELECT rowid AS rid,
              DENSE_RANK() OVER(PARTITION BY empno ORDER BY rowid) AS rn
              FROM emp
          )
          WHERE rn > 1
      );
      

      在这里您可以同时使用RANK()DENSE_RANK(),因为当rowid 订购时,两者都会给出唯一的记录。

      【讨论】:

        【解决方案8】:

        这是你应该做的事情:

        DELETE  FROM emp
        WHERE   rowid IN (
                SELECT  rid
                FROM    (
                          SELECT    rowid rid ,
                                    DENSE_RANK() OVER ( PARTITION BY empno ORDER BY rowid ) rn
                          FROM      emp
                        ) AS RR
                WHERE   rn > 1 );
        

        【讨论】:

        • 我怀疑这是否有帮助,甚至根本有效。为了说服我,请解释一下这段代码。
        猜你喜欢
        • 1970-01-01
        • 2012-02-21
        • 2019-06-09
        • 2015-10-08
        • 1970-01-01
        • 2017-04-06
        • 2010-12-08
        • 2020-11-04
        • 2017-08-11
        相关资源
        最近更新 更多