sql - SQL Server - 带有实际盘点的当前库存
问题描述
我觉得好像我错过了一些非常基本的东西,应该是显而易见的。我基本上是在尝试获取以下数据并计算第五列:Inventory_Current。
示例数据:
日期戳 | 产品编号 | 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 总和来计算当前库存水平。示例数据旨在简洁地捕捉这个概念。
预期结果:
日期戳 | 产品编号 | Inventory_Change | Inventory_Count | 库存_当前 |
---|---|---|---|---|
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
并将其添加到最后一个非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',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;
如果您不希望将 的值InventoryChange
计入具有非NULL
值的行,则需要CASE
在SUM
.
推荐阅读
- c# - 在 UWP Template10 App 中,后退按钮总是返回到起始页
- c++ - 如何擦除向量元素中没有特定字符的元素
- node.js - 使用 Telegram Bot API 检索受邀用户
- javascript - 由于 JavaScript 无休止的垃圾收集,IE 冻结
- c# - 是否可以在 C# 中创建非固定大小的数组?
- google-bigquery - 复制仅覆盖源表中的分区的分区 bigquery 表
- python - 使用 zip 命令从列表列表中获取所有列表的最后一个元素
- python - DataFrame 切片分配不一致
- c++ - 无法在另一个公共函数中调用公共函数
- sql - SQL Server:查找 1 行的多个索引(并找到这些索引)