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库存查询用于老化一个动态的单位数量的主要内容,如果未能解决你的问题,请参考以下文章

用于计算“保留”库存项目的 SQL 查询

select 多表关联查询

如何为需要从以前的订单计算的库存数量编写 SQL

化工行业存货分配的案例解析

化工行业存货分配的案例解析

SQL的一些查询语句