【问题标题】:SQL - Deleting duplicate columns only if another column matches [duplicate]SQL - 仅当另一列匹配时才删除重复列[重复]
【发布时间】:2019-01-19 22:32:11
【问题描述】:

我的下表 (TBL_VIDEO) 在“TIMESTAMP”中有重复的列条目,我想仅在“CAMERA”编号匹配时删除它们。

之前:

ANALYSIS_ID | TIMESTAMP | EMOTION | CAMERA
-------------------------------------------    
 1          | 5         | HAPPY   | 1
 2          | 10        | SAD     | 1
 3          | 10        | SAD     | 1
 4          | 5         | HAPPY   | 2
 5          | 15        | ANGRY   | 2
 6          | 15        | HAPPY   | 2

之后:

ANALYSIS_ID | TIMESTAMP | EMOTION | CAMERA
-------------------------------------------    
 1          | 5         | HAPPY   | 1
 2          | 10        | SAD     | 1
 4          | 5         | HAPPY   | 2
 5          | 15        | ANGRY   | 2

我已尝试此语句,但列不会相应地删除。我感谢所有帮助生成正确的 SQL 语句。提前致谢!

delete y
from TBL_VIDEO y 
where exists (select 1 from TBL_VIDEO y2 where y.TIMESTAMP = y2.TIMESTAMP and y2.ANALYSIS_ID < y.ANALYSIS_ID, y.CAMERA = y.CAMERA, y2.CAMERA = y2.CAMERA);

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    试试这个:

    delete f2 from (
    select row_number() over(partition by TIMESTAMP, CAMERA order by ANALYSIS_ID) rang
    from yourtable f1
    ) f2 where f2.rang>1
    

    【讨论】:

    • +1 这行得通。但只是一个小评论。如果您想将 delete f2 替换为 select * 以测试将删除的内容,则在子查询中添加字段非常方便。但这些实际上并不是删除所必需的。仅rang 就足够了。
    • 没错,我删除了它;)
    【解决方案2】:

    其他解决方案:

    delete f1 from yourtable f1
    where exists 
    (
      select * from yourtable f2
      where f2.TIMESTAMP=f1.TIMESTAMP and f2.CAMERA=f1.CAMERA and f1.ANALYSIS_ID>f2.ANALYSIS_ID
    )
    

    【讨论】:

    • 这行得通。谢谢!
    • 不客气 :)
    【解决方案3】:

    使用row_number 找到重复的并删除它们

    delete from
    (select *,row_number() over(partition by TIMESTAMP,CAMERA order by ANALYSIS_ID) as rn from TBL_VIDEO
    ) t1 where rn>1
    

    【讨论】:

      【解决方案4】:
      ;WITH cte
      AS
      (
          select ANALYSIS_ID,
          ROW_NUMBER() over(partition by TIMESTAMP, CAMERA order by ANALYSIS_ID) rnk
      )
      
      DELETE FROM cte WHERE cte.rnk > 1
      

      【讨论】:

        【解决方案5】:

        你可以使用subquery

        select v.*
        from tbl_video v
        where analysis_id = (select min(v1.analysis_id)
                             from tbl_video v1
                             where v1.timestamp = v.timestamp and
                                   v1.camera = v.camera 
                            );
        

        不过,带有top (1) with ties子句的解析函数也很有用:

        select top (1) with ties v.*
        from tbl_video v
        order by row_number() over (partition by v.timestamp, v.camera order by v.analysis_id);
        

        所以,您的delete 版本将是:

        delete v    
        from tbl_video v
        where analysis_id = (select min(v1.analysis_id)
                             from tbl_video v1
                             where v1.timestamp = v.timestamp and
                                   v1.camera = v.camera 
                            );
        

        【讨论】:

          猜你喜欢
          • 2020-06-29
          • 2019-07-25
          • 1970-01-01
          • 1970-01-01
          • 2018-08-03
          • 2012-11-26
          • 1970-01-01
          • 2019-01-19
          • 2013-08-01
          相关资源
          最近更新 更多