问题描述
我有一个结合了不同零件的库存、销售预测和未来供应数据的数据。我把它结合起来给我一个表格,它给出了每个部分每个月的净数量。见下文:
日期 | 部分 | 净数量 |
---|---|---|
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