【问题标题】:What is the efficient way to keep a duplicated record and delete all its duplicates?保留重复记录并删除所有重复记录的有效方法是什么?
【发布时间】:2020-05-14 01:57:54
【问题描述】:

这个查询听起来很简单,但在实现的情况下,它听起来就像看起来一样简单。

我的方法是

   Delete from
    Table where id IN(
   Select id from 
   ( Select id, 
   row_number() 
 Over (partition by id
   Order by id 
  ) as 
   Rn
   from
  Table )where rn>1)

【问题讨论】:

    标签: sql oracle duplicates sql-delete


    【解决方案1】:

    在 Oracle 中,这通常使用rowid 处理:

    delete from t
        where rowid not in (select min(rowid) from t group by id);
    

    如果您对id 有索引,我将其表述为:

    delete from t
        where rowid <> (select min(rowid) from t t2 where t2.id = t.id);
    

    编辑:

    完成此操作的唯一标准方法是清空表并重新插入数据。甚至这也会根据数据库进行调整。

    create table t_temp as
    select t.*
    from (select t.*, row_number() over (partition by id order by id) as seqnum
          from t
         ) t
    where seqnum = 1;
    
    alter table t_temp drop column seqnum;
    
    truncate table t;   -- back it up first!
    
    insert into t
        select *
        from t_temp;
    

    如果您有很多重复项,这也值得考虑。如果您要删除大部分行,那么这样做会更有效率。

    注意:并非所有数据库都支持create table as。那些不经常支持select into的人。

    【讨论】:

    • 戈登这将是所有数据库的标准?
    • @HimanshuAhuja 。 . .一点也不。该问题被标记为 Oracle,因此这是 Oracle 的答案。如果您对另一个数据库有疑问,请提出 问题。
    • 不。我的意思是我有多个数据库需要相同的逻辑,所以考虑一下是否也有一些标准
    • @Himanshu Ahuja:所有 RDBMS 的“标准”是对列具有唯一约束,因此一开始就不能产生重复。
    • 这种“标准”方式的一个问题是,有人可能会在您开始创建temp_t 之后但在您完成数据恢复之前尝试访问表t。有人可能会出错和/或可能丢失数据。由于truncate(和alter,我猜,就此而言),你不能锁定t
    【解决方案2】:

    您可以使用exists,如下:

    Delete from table_name t
    Where exists 
          (Select 1
             From table_name t1
            Where t.id = t1.id
              And t.rowid > t1.rowid)
    

    干杯!!

    【讨论】:

      猜你喜欢
      • 2015-09-27
      • 2019-12-20
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多