微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQL Server - 当前库存与物理计数

如何解决SQL Server - 当前库存与物理计数

我感觉好像我遗漏了一些应该很明显的非常基本的东西。我基本上是在尝试获取以下数据并计算第五列:Inventory_Current。

示例数据:

日期戳 产品ID Inventory_Change Inventory_Count
2021-07-01 100 -300 100000
2021-07-01 200 -700 50000
2021-07-02 100 200
2021-07-02 200 -100
2021-07-03 100 500
2021-07-03 200 300
2021-07-04 100 -1000 99500
2021-07-04 200 -100
2021-07-05 100 100
2021-07-05 200 300 50500

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

预期结果:

日期戳 产品ID 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 99900
2021-07-02 200 -100 49200
2021-07-03 100 500 100400
2021-07-03 200 300 49500
2021-07-04 100 -1000 99500 98500
2021-07-04 200 -100 49400
2021-07-05 100 100 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 组合似乎会导致问题。

即使是一些可靠阅读的链接也将不胜感激。或者远离孩子好好休息一晚。 :)

提前致谢。

解决方法

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

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',null),-100,('2021-07-03',500,300,('2021-07-04',-1000,99500),('2021-07-05',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,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 的值,则需要在 {{1} 中使用 CASE 表达式}}。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。