用上一行更新行
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
我有以下 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