用上一行更新行

Update Row with Previous Row

我有以下 table:

我正在尝试编写一个更新,用大于零的先前值填充零

我尝试了以下查询但没有成功

1.

With cte As
(
    SELECT [ID], [Q_G_R_BUOM], ROW_NUMBER() OVER (ORDER BY [ID] Asc) AS RN
    FROM [Testing_Lag]
)
update cte set [Q_G_R_BUOM]=iif([Q_G_R_BUOM]>0,[Q_G_R_BUOM],(SELECT [Q_G_R_BUOM] FROM cte WHERE [ID]=[ID]-1))
With cte As
(
    SELECT [ID], [Q_G_R_BUOM], ROW_NUMBER() OVER (ORDER BY [ID] Asc) AS RN
    FROM [Testing_Lag]
)
update cte set [Q_G_R_BUOM]=iif([Q_G_R_BUOM]>0,[Q_G_R_BUOM],(Lag([Q_G_R_BUOM], 1) OVER(ORDER BY [ID] ASC)))

如果有人能帮助我,我将不胜感激 谢谢

SQL 服务器中的一种方法使用可更新的 CTE 和 window 函数:

with toupdate as (
      select tl.*,
             max(Q_G_R_BUOM) over (partition by grp) as imputed_Q_G_R_BUOM
      from (select tl.*,
                   sum(case when Q_G_R_BUOM <> 0 then 1 else 0 end) over (order by id) as grp
            from testing_lag tl
           ) tl
     ) 
update toupdate
    set Q_G_R_BUOM = imputed_Q_G_R_BUOM
    where Q_G_R_BUOM = 0;

这会根据到该行的非零值的数量为每一行分配一个分组。然后它将这个值“传播”到整个组。

另一种方法使用 apply:

update tl
    set q_g_r_buom = tl2.q_g_r_buom
    from test_lag tl cross apply
         (select top (1) tl2.*
          from test_lag tl2
          where tl2.q_g_r_buom <> 0 and
                tl2.id < tl.id
          order by tl2.id
         ) tl2
    where tl.q_g_r_buom = 0

这个怎么样?

--DROP TABLE #C
CREATE TABLE #C (ID INT, Q_G_R_BUOM INT)
INSERT INTO #C values(1, 1805)
INSERT INTO #C values(2, 0)
INSERT INTO #C values(3, 0)
INSERT INTO #C values(4, 4732)
INSERT INTO #C values(5, 0)
INSERT INTO #C values(6, 0)

select * from #c

如果您的 table 中有空值,解决方案会有点不同。

SELECT ID,CASE WHEN Q_G_R_BUOM >0
            THEN Q_G_R_BUOM
            ELSE (SELECT max(Q_G_R_BUOM)
                  FROM #C
                  WHERE ID <= t.ID)
       END AS X
FROM #C t 

DROP TABLE #C
CREATE TABLE #C (ID INT, Q_G_R_BUOM INT)
INSERT INTO #C values(1, 1805)
INSERT INTO #C values(2, null)
INSERT INTO #C values(3, null)
INSERT INTO #C values(4, 4732)
INSERT INTO #C values(5, null)
INSERT INTO #C values(6, null)

select * from #c

SELECT ID,
COALESCE(Q_G_R_BUOM,
MAX(COALESCE(Q_G_R_BUOM,'')) OVER (ORDER BY ID  ROWS BETWEEN UNBOUNDED PRECEDING AND  1 PRECEDING)) AS Name
FROM #c