SQL 服务器 - 当前库存和实物盘点

SQL Server - current inventory with physical count

我觉得好像我缺少一些非常基本的东西,应该是显而易见的。我基本上是在尝试获取以下数据并计算第五列:Inventory_Current.

示例数据:

DateStamp ProductID Inventory_Change Inventory_Count
2021-07-01 100 -300 100000
2021-07-01 200 -700 50000
2021-07-02 100 200 null
2021-07-02 200 -100 null
2021-07-03 100 500 null
2021-07-03 200 300 null
2021-07-04 100 -1000 99500
2021-07-04 200 -100 null
2021-07-05 100 100 null
2021-07-05 200 300 50500

Inventory_Count 通常每月只执行一次,但销售规定 Inventory_Change 每天执行一次。因此,我需要根据每个 ProductID 自上次 Inventory_Count 以来的 Inventory_Change 总和来计算当前库存水平。示例数据旨在简洁地捕捉这个概念。

预期结果:

DateStamp ProductID Inventory_Change Inventory_Count Inventory_Current
2021-07-01 100 -300 100000 99700
2021-07-01 200 -700 50000 49300
2021-07-02 100 200 null 99900
2021-07-02 200 -100 null 49200
2021-07-03 100 500 null 100400
2021-07-03 200 300 null 49500
2021-07-04 100 -1000 99500 98500
2021-07-04 200 -100 null 49400
2021-07-05 100 100 null 98600
2021-07-05 200 300 50500 50800

要计算Inventory_Current,我大致遵循以下逻辑:

select
  DateStamp,
  ProductID,
  Inventory_Change,
  Inventory_Count,
  iif(Inventory_Count is not null,
    Inventory_Count+Inventory_Change,
    /*Do magic here*/
  ) as Inventory_Current
from
  Inventory

我考虑过 Itzik Ben-Gan 的 Last non Null 概念(很棒,顺便说一句),利用 LAG、OVER PARTITION 或放弃(SQL dba 不是我的主要角色, 明显地)。似乎最大的问题是所有解决方案都依赖于主键,而我的 DateStamp 和 ProductID 组合似乎会导致问题。

即使是 link 一些扎实的阅读也将不胜感激。或者离开 children 好好休息一晚。 :)

提前致谢。

没有预期结果(在撰写本文时),这是一个猜测,但是,我将 猜测 您想要累积 SUM InventoryChange 的值并将其添加到 InventoryCount 的最后一个非 NULL 值。如果是这样,那么也许这就是您所追求的:

CREATE TABLE dbo.YourTable (DateStamp date,
                            ProductID int,
                            InventoryChange int,
                            InventoryCount int);
GO
INSERT INTO dbo.YourTable
VALUES('2021-07-01',100,-300 , 100000),
      ('2021-07-01',200,-700 , 50000),
      ('2021-07-02',100,200  ,null),
      ('2021-07-02',200,-100 , null),
      ('2021-07-03',100,500  ,null),
      ('2021-07-03',200,300  ,null),
      ('2021-07-04',100,-1000,  99500),
      ('2021-07-04',200,-100 , null),
      ('2021-07-05',100,100  ,null),
      ('2021-07-05',200,300  ,50500);
GO
WITH Groups AS(
    SELECT DateStamp,
           ProductID,
           InventoryChange,
           InventoryCount,
           COUNT(InventoryCount) OVER (PARTITION BY ProductID ORDER BY DateStamp) AS Grp
    FROM dbo.YourTable)
SELECT DateStamp,
       ProductID,
       InventoryChange,
       CASE WHEN InventoryCount IS NOT NULL THEN InventoryCount + InventoryChange
            ELSE MAX(InventoryCount) OVER (PARTITION BY ProductID,Grp) +
                 SUM(InventoryChange) OVER (PARTITION BY ProductID,Grp ORDER BY DateStamp)
       END AS InventoryCount
FROM Groups
ORDER BY DateStamp;

GO

DROP TABLE dbo.YourTable;

db<>fiddle

如果您不希望 InventoryChange 的值计入具有非 NULL 值的行,您需要在 SUM.