使用重置条件在 SQL 中运行总计

问题描述

我有一个结合了不同零件的库存、销售预测和未来供应数据的数据。我把它结合起来给我一个表格,它给出了每个部分每个月的净数量。见下文:

日期 部分 数量
30/06/2021 A 1000
31/07/2021 A -150
31/08/2021 A -200
30/09/2021 A -500
31/10/2021 A -200
30/11/2021 A -200
31/12/2021 A 50
30/06/2021 B 100
31/07/2021 B -80
31/08/2021 B 20
30/09/2021 B -30
31/10/2021 B -35
30/11/2021 B -40
31/12/2021 B -150

我需要创建一个运行总计视图,该视图按零件编号进行分区,如果低于 0,则在下个月重置。如果上个月的期末库存为负,则运行总计的起点需要为 0。

我的预期结果是:

日期 部分 数量 期末库存(预期结果)
30/06/2021 A 1000 1000
31/07/2021 A -150 850
31/08/2021 A -200 650
30/09/2021 A -500 150
31/10/2021 A -200 -50
30/11/2021 A -200 -200
31/12/2021 A 50 50
30/06/2021 B 100 100
31/07/2021 B -80 20
31/08/2021 B 20 40
30/09/2021 B -30 10
31/10/2021 B -35 -25
30/11/2021 B -40 -40
31/12/2021 B -150 -150

我当前的代码是:

SELECT 
Date,Part,Net_Quantity,sum(Net_Quantity) over (partition by Part order by date) 'Closing_Inventory' 
FROM grouped

我不确定如何根据运行总计中的最后一个值创建条件,lag 函数无法查看运行总计的前一行。

解决方法

如果您提供一些示例数据会更容易,但我将如何解决此问题:

Declare @testData Table ([Date] date,Part char(1),NetQuantity int);
 Insert Into @testData ([Date],Part,NetQuantity)
 Values ('2021-06-30','A',1000),('2021-07-31',-150),('2021-08-31',-200),('2021-09-30',-500),('2021-10-31',('2021-11-30',('2021-12-31',50),('2021-06-30','B',100),-80),20),-30),-35),-40),-150);

   With runningTotal
     As (
 Select *,Inventory = sum(td.NetQuantity) over(Partition By td.Part Order By td.[Date])
   From @testData               td      
        )
 Select [Date],NetQuantity,ClosingInventory = iif(lag(Inventory,1,0) over(Partition By Part Order By [Date]) < 0,Inventory)
   From runningTotal;
,

这样的事情怎么样...

[错误答案已删除...]

编辑:

--Add a column...
ALTER TABLE PartsInventory ADD RowNumWithinPart int;

--Assign row numbers partitioned by Part...
UPDATE PartsInventory
SET RowNumWithinPart = x.rownum
FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY Part ORDER BY [Date]) as rownum,*
    FROM PartsInventory
) x
WHERE x.Part = PartsInventory.Part AND x.Date = PartsInventory.Date

--Recursive CTE solution:
WITH InvTotalsCTE AS
(
    SELECT [Date],RowNumWithinPart,Net_Quantity,Net_Quantity as Closing_Inventory
    FROM PartsInventory
    WHERE RowNumWithinPart = 1

    UNION ALL

    SELECT Q.[Date],Q.RowNumWithinPart,Q.Part,Q.Net_Quantity,iif(P.Closing_Inventory < 0,P.Closing_Inventory) + Q.Net_Quantity as Closing_Inventory
    FROM InvTotalsCTE as P
        JOIN PartsInventory Q ON (Q.RowNumWithinPart - 1) = P.RowNumWithinPart AND Q.Part = P.Part
)
SELECT [Date],Closing_Inventory
FROM InvTotalsCTE
ORDER BY Part,RowNumWithinPart