【问题标题】:Update Row with Previous Row用上一行更新行
【发布时间】:2021-06-08 17:33:11
【问题描述】:

我有下表:

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

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

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 asp.net sql-server tsql azure-sql-database


    【解决方案1】:

    SQL Server 中的一种方法使用可更新的 CTE 和窗口函数:

    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
    

    【讨论】:

    • 感谢回答,评论说更新一定要根据Asc ID,请问这个查询是这样工作的吗?
    • @Laureanorubioaguilar 。 . .这两个答案都依赖于id 来定义表格的顺序。两者都基于 id 采用“前面的”非0 值。
    【解决方案2】:

    这个怎么样?

    --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
    

    如果您的表中有空值,则解决方案会有所不同。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-28
      • 2016-07-12
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 2020-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多