使用之前行中的值更新行

Update row using value from row before

我正在使用之前行中的值查找更新行。

我有这样的东西:

Group by Value1 Value2 Value2 - expected result
1 0 20 20
1 3 x 23
1 5 x 28
1 2 x 30
2 0 30 30
2 5 x 35
2 2 x 37

Value2 = 前一行的 Value2 + 值 1 但“分组依据”列很重要。如果之前的 Value2 在另一个组中,则: Value2 = Value2

sameone可以解释一下这个更新语句是怎么做的吗?我尝试将 CTE 与 LAG 函数一起使用,但我总是陷入无限循环。

Code for create table:
create table test
(
  [GroupBy] int
, [Date] date
, [Value1] int
, [Value2] int
)

正在插入数据:

    INSERT INTO test ([GroupBy], [Date] [Value1], [Value2])
VALUES 
(1, '2022-01-01', 0, 20),
(1, '2022-01-02', 3, NULL),
(1, '2022-01-03', 5, NULL),
(1, '2022-01-04', 2, NULL),
(2, '2022-01-01', 0, 30),
(2, '2022-01-02', 5, NULL),
(2, '2022-01-03', 2, NULL)

主键依据:[GroupBy]、[日期]

使用 LAG function

检查
-- Using LAG function
-- https://docs.microsoft.com/sql/t-sql/functions/lag-transact-sql?view=sql-server-ver15&WT.mc_id=DP-MVP-5001699
;With MyCTE as (
    SELECT  
        t.[date], t.GroupBy,t.Value1,Value2 = ISNULL(t.Value2,0), 
        PreValue2 = ISNULL(LAG(t.Value2,1,0) OVER (PARTITION BY t.GroupBy ORDER BY [date]),0)
    FROM test t
)
SELECT [date], GroupBy, Value1, Value2, PreValue2, [Value1+PreValue2] = Value1+PreValue2
FROM MyCTE

根据评论,也许原始请求没有很好地描述,您需要的不是“前一行的 Value2 + 值 1”,而是“前所有行的所有 Value2 的总和 + 值 1”

在这种情况下,检查这个解决方案

-- Value1 + total of all previous Value2
;With MyCTE as (
    SELECT  
        t.[date], t.GroupBy,t.Value1,Value2 = ISNULL(t.Value2,0) 
        ,TotalPreValue2 = SUM(ISNULL(t.Value2,0)) 
            OVER (PARTITION BY t.GroupBy ORDER BY [date] ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW)
    FROM test t
)
SELECT [date], GroupBy, Value1, Value2, TotalPreValue2, [Value1+TotalPreValue2] = Value1+TotalPreValue2
FROM MyCTE
GO

如果你需要其他东西,比如“前面所有行的所有 Value2 的总和 + 前面所有行的所有 value1 的总和”,然后检查这个

--  total of all previous Value1 + total of all previous Value2
;With MyCTE as (
    SELECT  
        t.[date], t.GroupBy,t.Value1,Value2 = ISNULL(t.Value2,0) 
        ,TotalPreValue2 = SUM(ISNULL(t.Value2,0)) 
            OVER (PARTITION BY t.GroupBy ORDER BY [date] ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW)
        ,TotalPreValue1 = SUM(ISNULL(t.Value1,0)) 
            OVER (PARTITION BY t.GroupBy ORDER BY [date] ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW)
    FROM test t
)
SELECT [date], GroupBy, Value1, Value2, TotalPreValue2, TotalPreValue1, [TotalPreValue1+TotalPreValue2] = TotalPreValue1+TotalPreValue2
FROM MyCTE