查找重复项并更新T-SQL

时间:2014-03-18 10:22:25

标签: sql sql-server-2008 tsql

我有下表

TABLE GrantedService(
 GUID [uniqueidentifier] NOT NULL PK,   
 ServiceTypeGUID [uniqueidentifier] NOT NULL,
 ServiceOrderGUID [uniqueidentifier] NULL,
 ValidFrom datetime
 ValidTo datetime
 Description [varchar](max) NULL,
 ExternalID [varchar](40) NULL
)

此表包含重复项,其中副本是ServiceTypeGUID和ServiceOrderGUID的组合。 I.E.相同的ServiceTypeGUID不应多次使用与当前相同的ServiceOrderGUID出现。

我需要的是找到重复项并将ValidTo设置为具有最高ExternalID的副本的ValidFrom日期,并将其ValidTo日期保留为null。

我开始找到这样的副本:

with x as(

select *,rn=ROW_NUMBER() 
over(PARTITION by ServiceTypeGUID,ServiceOrderGUID order by ExternalID DESC) 
from GrantedService where ValidTo is null

)select * from x where rn>1

关于如何从这里或任何其他方法进行的任何想法?

2 个答案:

答案 0 :(得分:3)

如果" ValidFrom来自具有最高ExternalID&#34的副本的日期;是ValidFrom的最大值,您可以这样做:

with toupdate as (
      select *,
             ROW_NUMBER() as seqnum over (partition by ServiceTypeGUID, ServiceOrderGUID
                                          order by ExternalID DESC
                                         ),
             max(validfrom) over (partition by ServiceTypeGUID, ServiceOrderGUID) as maxValidFrom
     from GrantedService
     where ValidTo is null
    )
update toupdate
    set ValidTo = maxValidFrom
    where seqnum > 1 and ValidTo is NULL;

如果您使用的是SQL Server 2012,则可以使用first_value()

with toupdate as (
      select *,
             ROW_NUMBER() as seqnum over (partition by ServiceTypeGUID, ServiceOrderGUID
                                          order by ExternalID DESC
                                         ),
             first_value(validfrom) over (partition by ServiceTypeGUID, ServiceOrderGUID
                                          order by ExternalID DESC
                                         ) as lastValidFrom
     from GrantedService
     where ValidTo is null
    )
update toupdate
    set ValidTo = maxValidFrom
    where seqnum > 1;

如果这两个条件都不成立,那么查询会有点复杂但仍有可能。

答案 1 :(得分:0)

你的方法很好,你只需要在结尾处使用DELETE而不是SELECT。

WITH x AS(
SELECT ROW_NUMBER() 
OVER (PARTITION BY ServiceTypeGUID, ServiceOrderGUID
ORDER BY ExternalID DESC) 
FROM GrantedService WHERE ValidTo IS NULL
) DELETE FROM x WHERE RN > 1

我将你的SELECT与WHERE RN一起使用> 1确保使用DELETE删除您期望的重复行。