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;
如果您不希望 InventoryChange
的值计入具有非 NULL
值的行,您需要在 SUM
.
我觉得好像我缺少一些非常基本的东西,应该是显而易见的。我基本上是在尝试获取以下数据并计算第五列: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;
如果您不希望 InventoryChange
的值计入具有非 NULL
值的行,您需要在 SUM
.