SQL FIFO库存查询用于老化一个动态的单位数量
Posted
技术标签:
【中文标题】SQL FIFO库存查询用于老化一个动态的单位数量【英文标题】:SQL FIFO inventory query for aging a dynamic number of units 【发布时间】:2020-10-13 21:40:45 【问题描述】:我有下面的库存交易表,我想用它来确定我销售的单位的年龄。
我想要一个脚本,允许我输入要购买的单位数量,结果会根据 FIFO 逻辑显示将选择哪些单位。
类型标识事务是 IN 还是 OUT。
示例:客户想在 1 月 31 日购买 50 件。
我的表在 1 月 31 日之前有以下交易。
id date units type
1 Jan 1 10 1
2 Jan 10 45 1
3 Jan 12 -15 -1
4 Jan 25 20 1
第 1 步:使用 SQL 窗口函数应用 FIFO
drop table if exists ##transactions
go
select *
into ##transactions
FROM (
select 1 id, '1/1/2020' date, 10 units, 1 type UNION ALL
select 2 id, '1/10/2020' date, 45 units, 1 type UNION ALL
select 3 id, '1/12/2020' date, -15 units, -1 type UNION ALL
select 4 id, '1/25/2020' date, 20 units, 1 type
) a
SELECT id, date, units, IIF(cumulative > 0, cumulative, 0) cumulative FROM (
SELECT id, date, units, SUM(units) OVER (ORDER BY type, date) AS cumulative FROM ##transactions
) a
ORDER BY date
结果:
id date units cumulative
1 Jan 1 10 0
2 Jan 10 45 40
3 Jan 12 -15 0
4 Jan 25 20 60
第 2 步:选择 X 个单位(其中 X = 50)
code help please
结果(期望):
id date units cumulative selected
1 Jan 1 10 0 0
2 Jan 10 45 40 40
3 Jan 12 -15 0 0
4 Jan 25 20 60 10
这将告诉我,我 1 月 10 日库存中的 40 个单位和 1 月 25 日库存中的 10 个单位将被挑选出来。
我希望该过程以我可以输入任何数字的方式工作,并且结果集将根据 FIFO 返回正确的可用值。
【问题讨论】:
我不理解您对窗口总和的期望逻辑 - 我看不出第 1 步中的查询将如何生成您所显示的结果。 @GMB 我更新了查询以显示确切的结果。感谢您的意见。 【参考方案1】:declare @amount_to_deduct int = 50
SELECT *,
case when cumulative = 0 or units < 0 then 0
when cumulative < @amount_to_deduct and cumulative < units then cumulative
when cumulative < @amount_to_deduct and cumulative >= units then units
when cumulative - units < @amount_to_deduct and cumulative < units then @amount_to_deduct
when cumulative - units < @amount_to_deduct and cumulative >= units then @amount_to_deduct - cumulative + units
else 0
end as selected
FROM (
SELECT id, date, units, IIF(cumulative > 0, cumulative, 0) cumulative
FROM (
SELECT id, date, units, SUM(units) OVER (ORDER BY type, date) AS cumulative FROM transactions
) a
) b
ORDER BY date
这是一个带有一些额外测试数据的 sql fiddle:http://sqlfiddle.com/#!18/b0584/10
我使用该样本测试了 50、30、100 和 150 的案例,数据看起来是正确的
【讨论】:
谢谢,我相信这适用于所有场景。非常感谢。【参考方案2】:我认为这是cumulative
和条件逻辑的窗口总和:
select id, date, units,
case
when sum(cumulative) over(order by date) < 50
then cumulative
when sum(cumulative) over(order by date) - cumulative < 50
then 50 - sum(cumulative) over(order by date) + cumulative
else 0
end as selected
from (
select id, date, units,
case when sum(units) over (order by type, date) > 0
then sum(units) over (order by type, date)
else 0
end as cumulative
from ##transactions
) a
order by date
Demo on DB Fiddle - 我在表格末尾添加了另一行来演示达到目标数量后“下一个”库存行会发生什么:
编号 |日期 |单位 |选择 -: | :-------- | ----: | --------: 1 | 2020 年 1 月 1 日 | 10 | 0 2 | 2020 年 1 月 10 日 | 45 | 40 3 | 2020 年 1 月 12 日 | -15 | 0 4 | 2020 年 1 月 25 日 | 20 | 10 4 | 2020 年 1 月 26 日 | 30 | 0【讨论】:
非常接近,但请看这个小提琴:FIDDLE @warrenk:有什么问题? 我的小提琴中的日期格式错误,现在已更新:FIDDLE 您现在可能会在 id = 4 行看到问题。单位数是 16,但选择的单位是22. 我不能卖出比我拥有的更多的单位。以上是关于SQL FIFO库存查询用于老化一个动态的单位数量的主要内容,如果未能解决你的问题,请参考以下文章