Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 需要删除一种项目类型的重复行,但不删除其他项目类型的重复行_Sql_Tsql_Sql Server 2008 R2 - Fatal编程技术网

Sql 需要删除一种项目类型的重复行,但不删除其他项目类型的重复行

Sql 需要删除一种项目类型的重复行,但不删除其他项目类型的重复行,sql,tsql,sql-server-2008-r2,Sql,Tsql,Sql Server 2008 R2,我有一个基本的select语句,如下所示: SELECT ID, ProcedureCode, CONVERT(VARCHAR(8), StartTime, 112) AS 'DateOfService', SessionID' FROM dbo.TASK ID ProcedureCode DateOfService SessionID A164686 0034 20131014 9708 A1646

我有一个基本的select语句,如下所示:

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
结果如下:

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 B46333,10月份有三个0002程序。我想消除额外的两个,只留下基于DateOfService的最新版本

我知道我可以通过使用行数分区来实现这一点,但我不希望这种逻辑应用于其他过程代码,如0034,我只想删除额外的0002过程代码(如果它们存在)。复制0034是可以的,但不是0002


有没有想过如何做到这一点?我认为能够做到这一点的唯一方法是使用0002程序代码制作一个临时表,并对上面的选择进行联合,但这看起来很混乱。

您可以使用一个排序函数,如ROW_NUMBER,并使用一个公共表函数:

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

这不也适用于非0002过程代码吗?@user2932397:它将根据ID ProcedureCode只删除重复项。然而,我必须承认,我只读了第一段,没有读到开头的部分,我知道我可以通过使用行数来完成这一点。编辑:我已经编辑了我的答案。您只需在CTE或DELETE语句中添加一个Where即可。我看不出这个解决方案是如何工作的,因为ProcedureCode='0002'有一个Where子句,这意味着我将排除0034和其他几个过程代码。@Baub:这是您的话:但我不希望这种逻辑应用于其他过程代码,如0034,我只想删除额外的0002程序代码(如果存在)。复制0034是可以的,但不是0002。这意味着您只想删除@user2932397还提到的重复的0002行。我误解了吗?是的,我只想删除0002的重复行,但0034和其他行的重复行是可以接受的。如果我运行select语句,我将永远不会有0034的过程代码,但我需要包括这些代码。