SQL Server 2012中基于当前行修改下一行并删除当前行的实现求助
解决SQL Server 2012中临时表行数据累加与删除的问题
嘿,我来帮你搞定这个需求!你想要把临时表中ReasonString_S = 'Fault Reset'的行的DurationMinutes_D值加到下一行,然后删除当前行对吧?之前用CASE WHEN碰壁是因为它只能处理当前行的数据,没法直接关联到下一行的内容——我们需要用自连接或者窗口函数来处理行与行之间的关联,SQL Server 2012正好支持这些特性。
下面给你两种可行的方案,你可以根据实际场景选择:
方案一:直接生成处理后的结果集(不修改原临时表)
如果不需要修改原临时表,只是想要得到最终的处理后数据,用CTE(公共表表达式)结合窗口函数会很清晰。这个方案还能处理连续多个Fault Reset行的情况,把它们的总时长一次性加到下一个有效行:
WITH GroupedData AS ( -- 先给每行标记分组:连续的Fault Reset属于同一个前置组,非Fault Reset行作为独立组 SELECT *, SUM(CASE WHEN ReasonString_S <> 'Fault Reset' THEN 1 ELSE 0 END) OVER (ORDER BY Row) AS GroupId FROM #temptable ), SummedFaultDurations AS ( -- 计算每个前置组中所有Fault Reset行的总时长 SELECT GroupId, SUM(DurationMinutes_D) AS TotalFaultDuration FROM GroupedData WHERE ReasonString_S = 'Fault Reset' GROUP BY GroupId ) -- 组合数据:给非Fault Reset行加上对应前置组的总时长,同时过滤掉Fault Reset行 SELECT gd.Row, gd.equip_name, gd.ReasonString_S, gd.DurationMinutes_D + ISNULL(sf.TotalFaultDuration, 0) AS DurationMinutes_D, gd.ProcStateString, gd.EntryDate_T FROM GroupedData gd LEFT JOIN SummedFaultDurations sf ON gd.GroupId = sf.GroupId WHERE gd.ReasonString_S <> 'Fault Reset' ORDER BY gd.Row;
方案二:直接修改临时表(更新+删除)
如果你需要直接修改原临时表#temptable,可以先更新下一行的时长,再删除Fault Reset行。这个方案会直接改变临时表的数据:
-- 第一步:把每个Fault Reset行的时长加到它的下一行 UPDATE t2 SET t2.DurationMinutes_D = t2.DurationMinutes_D + t1.DurationMinutes_D FROM #temptable t1 INNER JOIN #temptable t2 ON t1.Row = t2.Row - 1 WHERE t1.ReasonString_S = 'Fault Reset'; -- 第二步:删除所有Fault Reset行 DELETE FROM #temptable WHERE ReasonString_S = 'Fault Reset';
小提示
- 你的原始查询已经用
ROW_NUMBER()生成了按EntryDate_T排序的Row列,这非常关键——它保证了我们能准确找到每一行的下一行。 - 如果你的数据中存在连续多个
Fault Reset行,方案二会自动把每一行的时长依次累加到下一行,最终下一个有效行会得到所有连续Fault Reset的总时长,这和方案一的效果是一致的。
内容的提问来源于stack exchange,提问作者user3055889
相关产品推荐
相关产品推荐

