喜雅生活 > 杂谈 > 正文

​sql删除重复数据只保留一条(sqlserver删除重复数据只保留一条,使用ROW_NUM

2024-01-09 01:38 来源:喜雅生活 点击:

sql删除重复数据只保留一条(sqlserver删除重复数据只保留一条,使用ROW_NUMER()与Partition By)

1.使用场景: 公司的小程序需要实现一个功能:在原有小程序上,有一个优惠券活动表。 存储着活动产品数据,但因为之前没有做约束,导致数据的不唯一,这会使打开产品详情页时,可能会出现随机显示任意活动问题。 因此需要把它删除掉。

2.那么如何删除呢? 通过翻阅资料发现我们可以通过使用Row_Number()与Partition By 来实现这个功能,我们先看看Row_Number()如何使用,它的语法是:

1).Row_Number() Over ():对结果集的输出进行编号。 具体来说,返回结果集分区内行的序列号,每个分区的第一行从 1 开始。ROW_NUMBER 按顺序对所有行进行编号(例如 1、2、3、4、5)。

如果我们只使用Row_Number() Over( Order By xxx),我们就到序号,如图:

若是在 recovery_model_desc 列上添加 PARTITION BY 子句,当 recovery_model_desc 值发生更改时将重新开始编号。就可以得到如下图结果:

以上都是网上提供的资料,现在,再回到我要解决的问题:

第一步:我们要把活动产品表 XXX_PRODUCT表进行分组:

SELECT UniqueId, PromoteId, ProductId, ROW_NUMBER() OVER ( PARTITION BY PromoteId, ProductId ORDER BY UniqueId DESC) rownum
FROM STAR_PROMOTE_PRODUCT

此处是按产品ID,活动ID进行分区,在每个分区里按UniqueId倒排序(这样我们就可以保留重复数据中最新的,删除旧的),并把每个分区各自按顺序排列生成的行序号RowNum。

第二步,我们再取出要删除的唯一键

SELECT temp.UniqueId FROM (
SELECT UniqueId, PromoteId, ProductId, ROW_NUMBER() OVER ( PARTITION BY PromoteId, ProductId ORDER BY UniqueId DESC) rownum
FROM STAR_PROMOTE_PRODUCT) RowNum
FROM STAR_PROMOTE_PRODUCT

最后,我们再删除该唯一键

DELETE FROM 活动产品表
WHERE UniqueID IN(
SELECT temp.UniqueId FROM (
SELECT UniqueId, PromoteId, ProductId, ROW_NUMBER() OVER ( PARTITION BY PromoteId, ProductId ORDER BY UniqueId DESC) RowNum
FROM 活动产品表) as temp
WHERE temp.rownum > 1)

注意这里的temp.rownum > 1,表示删除序号大于1的记录,因为重复可能有多条。因为>1就保留

最新的一条记录,删除其它旧的重复记录。