T SQL 基于上一个字段的游标更新字段
T SQL Cursor Update field based on previous field
我正在使用 SQL Server 2016。
我有这个 table:
RowID SKU Shop Week Prioirty Replen Open_Stk
---------------------------------------------------------------
1 111 100 1 1 400 5000
2 111 200 1 2 400 NULL
3 111 300 1 3 400 NULL
4 111 400 1 4 400 NULL
这是期望的结果:
RowID SKU Shop Week Prioirty Replen Open_Stk
---------------------------------------------------------------
1 111 100 1 1 400 5000
2 111 200 1 2 400 4600
3 111 300 1 3 400 4200
4 111 400 1 4 400 3800
Open_Stk 的计算基于上一行:
[Open_Stk] = [Open_Stk]-IIF([Replen]<=IIF([Open_Stk]>=0,[Open_Stk],0),[Replen],0)
我正在使用下面的光标更新 Open_Stk 但没有任何反应 - 我错过了什么:
DECLARE @CurrentRow INT;
DECLARE @PreviousRow INT
DECLARE ShopRank CURSOR FOR
SELECT RowID
FROM [tmp_tblTEST]
ORDER BY [SKU], [Week],Priority
OPEN ShopRank
FETCH NEXT FROM ShopRank INTO @CurrentRow
WHILE @@FETCH_STATUS = 0
BEGIN
IF ((SELECT [Open_Stk] FROM [tmp_tblTEST] WHERE RowID = @CurrentRow) IS NULL)
BEGIN
UPDATE [tmp_tblTEST]
SET [Open_Stk] = [Open_Stk] - IIF([Replen] <= IIF([Open_Stk] >= 0, [Open_Stk], 0), [Replen], 0)
WHERE RowID = @PreviousRow
END
SET @PreviousRow = @CurrentRow
FETCH NEXT FROM ShopRank INTO @CurrentRow
END
CLOSE ShopRank
DEALLOCATE ShopRank
这里根本不需要CURSOR
。这是一些猜测工作,但我 怀疑 你真正想要的是这样的:
SELECT V.RowID,
V.SKU,
V.Shop,
V.[Week],
V.Priority,
V.Replen,
FIRST_VALUE(V.Open_Stk) OVER (PARTITION BY V.SKU ORDER BY V.[Week], V.Priority
ROWS UNBOUNDED PRECEDING) -
ISNULL(SUM(V.Replen) OVER (PARTITION BY V.SKU ORDER BY V.[Week], V.Priority
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),0) AS OpenStk
FROM (VALUES (1,111,100,1,1,400,5000),
(2,111,200,1,2,400,NULL),
(3,111,300,1,3,400,NULL),
(4,111,400,1,4,400,NULL))V(RowID,SKU,Shop,[Week],Priority,Replen,Open_Stk)
ORDER BY V.Sku,
V.[Week],
V.Priority;
DB<>Fiddle (使用原解)
FIRST_VALUE
言出必行。 SUM
从第一行的 Open_Stk
值中减去每个 prior 行的值;制作最终的结果集。由于 ROWS BETWEEN
子句,它仅引用前面的行。 ROWS UNBOUNDED
表示从分区范围的开头开始,1 PRECEDING
表示行prior.
WITH result AS
(
SELECT
a.*, ISNULL(NULLIF(a.Open_Stk, 0), 0) AS Output
FROM
table1 a
JOIN
table1 b ON a.Prioirty = b.Prioirty - 1
UNION ALL
SELECT
a.*, output - a.Replen
FROM
table1 a
JOIN
result b ON a.Prioirty = b.Prioirty+1
)
SELECT *
FROM result
WHERE output > 0
我正在使用 SQL Server 2016。
我有这个 table:
RowID SKU Shop Week Prioirty Replen Open_Stk
---------------------------------------------------------------
1 111 100 1 1 400 5000
2 111 200 1 2 400 NULL
3 111 300 1 3 400 NULL
4 111 400 1 4 400 NULL
这是期望的结果:
RowID SKU Shop Week Prioirty Replen Open_Stk
---------------------------------------------------------------
1 111 100 1 1 400 5000
2 111 200 1 2 400 4600
3 111 300 1 3 400 4200
4 111 400 1 4 400 3800
Open_Stk 的计算基于上一行:
[Open_Stk] = [Open_Stk]-IIF([Replen]<=IIF([Open_Stk]>=0,[Open_Stk],0),[Replen],0)
我正在使用下面的光标更新 Open_Stk 但没有任何反应 - 我错过了什么:
DECLARE @CurrentRow INT;
DECLARE @PreviousRow INT
DECLARE ShopRank CURSOR FOR
SELECT RowID
FROM [tmp_tblTEST]
ORDER BY [SKU], [Week],Priority
OPEN ShopRank
FETCH NEXT FROM ShopRank INTO @CurrentRow
WHILE @@FETCH_STATUS = 0
BEGIN
IF ((SELECT [Open_Stk] FROM [tmp_tblTEST] WHERE RowID = @CurrentRow) IS NULL)
BEGIN
UPDATE [tmp_tblTEST]
SET [Open_Stk] = [Open_Stk] - IIF([Replen] <= IIF([Open_Stk] >= 0, [Open_Stk], 0), [Replen], 0)
WHERE RowID = @PreviousRow
END
SET @PreviousRow = @CurrentRow
FETCH NEXT FROM ShopRank INTO @CurrentRow
END
CLOSE ShopRank
DEALLOCATE ShopRank
这里根本不需要CURSOR
。这是一些猜测工作,但我 怀疑 你真正想要的是这样的:
SELECT V.RowID,
V.SKU,
V.Shop,
V.[Week],
V.Priority,
V.Replen,
FIRST_VALUE(V.Open_Stk) OVER (PARTITION BY V.SKU ORDER BY V.[Week], V.Priority
ROWS UNBOUNDED PRECEDING) -
ISNULL(SUM(V.Replen) OVER (PARTITION BY V.SKU ORDER BY V.[Week], V.Priority
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),0) AS OpenStk
FROM (VALUES (1,111,100,1,1,400,5000),
(2,111,200,1,2,400,NULL),
(3,111,300,1,3,400,NULL),
(4,111,400,1,4,400,NULL))V(RowID,SKU,Shop,[Week],Priority,Replen,Open_Stk)
ORDER BY V.Sku,
V.[Week],
V.Priority;
DB<>Fiddle (使用原解)
FIRST_VALUE
言出必行。 SUM
从第一行的 Open_Stk
值中减去每个 prior 行的值;制作最终的结果集。由于 ROWS BETWEEN
子句,它仅引用前面的行。 ROWS UNBOUNDED
表示从分区范围的开头开始,1 PRECEDING
表示行prior.
WITH result AS
(
SELECT
a.*, ISNULL(NULLIF(a.Open_Stk, 0), 0) AS Output
FROM
table1 a
JOIN
table1 b ON a.Prioirty = b.Prioirty - 1
UNION ALL
SELECT
a.*, output - a.Replen
FROM
table1 a
JOIN
result b ON a.Prioirty = b.Prioirty+1
)
SELECT *
FROM result
WHERE output > 0