需要删除一个项类型的重复行,而不删除其他项

时间:2013-11-25 20:55:36

标签: sql tsql sql-server-2008-r2

我有一个像这样的基本选择语句:

SELECT  
        ID, ProcedureCode, CONVERT(VARCHAR(8), StartTime, 112) AS 'DateOfService',
        SessionID'

 FROM dbo.TASK

结果是这样的:

 ID     ProcedureCode   DateOfService   SessionID
A164686     0034        20131014        9708
A164686     0034        20131021        9832
A164686     0002        20131007        9578
B463333     0002        20131003        9523
B463333     0002        20131009        9665
B463333     0002        20131016        9763

ID B463333的注释10月份有三个0002程序。我想消除额外的两个只留下最新的(基于DateOfService)。

我知道我可以通过使用row_number()分区完成此操作,但我不希望该逻辑应用于其他过程代码,如0034,我只想删除额外的0002过程代码(如果它们存在)。复制0034很好,但不是0002。

有关如何实现这一点的想法?我想到能够做到这一点的唯一方法是使用0002程序代码创建一个临时表,并对上面的选择执行UNION,但这看起来很混乱。

1 个答案:

答案 0 :(得分:1)

您可以使用像ROW_NUMBER这样的排名函数和common-table-function:

WITH CTE AS
(
     SELECT  ID, 
             ProcedureCode, 
             CONVERT(VARCHAR(8), StartTime, 112) AS 'DateOfService', 
             SessionID,
             RN = ROW_NUMBER() OVER (PARTITION BY ID, ProcedureCode 
                                     ORDER BY StartTime DESC)
     FROM dbo.TASK
     WHERE  ProcedureCode = '0002'
)
DELETE FROM CTE WHERE RN > 1

一个优点是您可以更改它以轻松选择以查看您要删除的内容。

编辑:如果您实际上不想“消除”(删除)记录但忽略结果集中不需要的行,则可以使用此查询:

WITH CTE AS
(
     SELECT  ID, 
             ProcedureCode, 
             CONVERT(VARCHAR(8), StartTime, 112) AS 'DateOfService', 
             SessionID,
             RN = ROW_NUMBER() OVER (PARTITION BY ID, ProcedureCode 
                                     ORDER BY StartTime DESC)
     FROM dbo.TASK
)
SELECT ID, ProcedureCode, DateOfService, SessionID
FROM CTE
WHERE ProcedureCode <> '0002'
OR    RN = 1