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