You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用T-SQL实现基于上一行NetWeight更新当前行NetWeight?

解决SQL Server逐行累计更新NetWeight的问题

你之前用CTE+LAG函数失败的原因是:LAG取的是表中原始的上一行NetWeight值,而更新操作是批量执行的,所有行的更新逻辑都基于更新前的数据,导致只有第一行能正确更新,后续行没法用到前一行更新后的结果。

下面给两种靠谱的解决方案:

方案1:用窗口函数计算累计和(推荐,效率更高)

其实你要的NetWeight本质就是TransactionWeight的累计求和值,直接用窗口函数SUM() OVER()一次性算出所有行的正确结果,再批量更新即可:

WITH CTE AS (
    SELECT 
        Id,
        NetWeight,
        -- 按Id排序,计算从第一行到当前行的TransactionWeight累计和
        SUM(TransactionWeight) OVER (ORDER BY Id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS NewNetWeight
    FROM Table1
)
UPDATE CTE
SET NetWeight = NewNetWeight;

这个方法不需要逐行依赖,所有行的正确值一次性计算完成,更新效率远高于游标。

方案2:用游标逐行更新(适合复杂自定义逻辑)

如果你的业务逻辑比单纯累计更复杂,必须逐行使用前一行更新后的结果,可以用游标实现:

DECLARE @PrevNetWeight DECIMAL(18,2)
DECLARE @CurrentId INT
DECLARE @CurrentTransWeight DECIMAL(18,2)

-- 按Id顺序获取所有行数据
DECLARE UpdateCursor CURSOR FOR
SELECT Id, TransactionWeight
FROM Table1
ORDER BY Id

OPEN UpdateCursor
-- 取第一行初始化
FETCH NEXT FROM UpdateCursor INTO @CurrentId, @CurrentTransWeight
SET @PrevNetWeight = @CurrentTransWeight
UPDATE Table1 SET NetWeight = @PrevNetWeight WHERE Id = @CurrentId

-- 循环处理剩余行
FETCH NEXT FROM UpdateCursor INTO @CurrentId, @CurrentTransWeight
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @PrevNetWeight = @PrevNetWeight + @CurrentTransWeight
    UPDATE Table1 SET NetWeight = @PrevNetWeight WHERE Id = @CurrentId
    FETCH NEXT FROM UpdateCursor INTO @CurrentId, @CurrentTransWeight
END

-- 清理游标
CLOSE UpdateCursor
DEALLOCATE UpdateCursor

游标是逐行处理的,每一行更新都会基于前一行更新后的NetWeight值,完全符合你的需求,但注意游标在数据量大时效率较低,优先用方案1。

内容的提问来源于stack exchange,提问作者sss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:22:12