计算一段时间内不同的累积存储费用?

时间:2019-10-15 09:28:52

标签: sql sql-server

我正在为一个葡萄酒进口商开展一个项目,该项目需要计算到交货日期为止每个SKU的累计仓储费。

我从仓库中记录了Date_InDate_Out的数据,因此计算DATEDIFF('day', Date_In, Date_Out)相当简单。 但是,每年仓库都会改变价格,因此在计算仓储费用时,我需要将Days_in_Stock分配给不同的费率。

输入具有库存变动日期的数据:

+----------------+------------+---------+-----+------------+------------+
| INVOICE_NUMBER | STOCK_CODE | CS_SIZE | QTY |  DATE_IN   |  DATE_OUT  |
+----------------+------------+---------+-----+------------+------------+
|           1001 | MP-BMB13   |       6 |   1 | 2019-03-01 | 2019-06-01 |
|           1002 | MP-BMB13   |       6 |   1 | 2019-03-01 | 2019-10-01 |
+----------------+------------+---------+-----+------------+------------+

存储率:

+----------------+-----------+-------------+
| DATE_EFFECTIVE | CASE_SIZE | COST_PER_WK |
+----------------+-----------+-------------+
| 2018-09-01     |         9 |      0.1375 |
| 2018-09-01     |         6 |     0.06875 |
| 2019-09-01     |         9 |      0.1425 |
| 2010-09-01     |         6 |     0.07125 |
+----------------+-----------+-------------+

我想要的输出如下:

+----------------+------------+---------------+--------------+
| INVOICE_NUMBER | STOCK_CODE | DAYS_IN_STOCK | STORAGE_COST |
+----------------+------------+---------------+--------------+
|           1001 | MP-BMB13   |            92 |         0.90 |
|           1002 | MP-BMB13   |           214 |         2.10 |
+----------------+------------+---------------+--------------+

DAYS_IN_STOCKDATEDIFF('day', Date_In, Date_Out)

计算

STORAGE_COSTCOST_PER_WK * DAYS_IN_STOCK / 7

我遇到的问题是DAYS_IN_STOCK与Invoice 1002一样跨越多个收费率。在这种情况下,计算需要像这样:

COST_PER_WK (before 2019-09-01)* DAYS_IN_STOCK (before 2019-09-01) / 7
+ 
COST_PER_WK (since 2019-09-01)* DAYS_IN_STOCK (since 2019-09-01) / 7

理想情况下,最终查询将能够处理该商品在两个以上的收费时段内的库存情况。

到目前为止尝试的方法:

  • 很难对查询进行编码以找到费率变化前后的天数,但是我最终将需要使用5年之前的数据,并为更复杂的交货费率表实施相同的操作。
  • 试图将Date_In联接到Date_Effective,但我无法使其正常工作,也不知道如何扩展到3个价格。

我对如何解决这个问题感到很困惑,因此任何想法都将受到欢迎。 当前正在使用SQL Server 2017

1 个答案:

答案 0 :(得分:0)

这应该为您提供解决方法的思路。我不想处理数周,因此我将用几天来表达这个答案。

基本思想是将结束日期添加到费率表,然后使用join和汇总:

with sr as (
      select r.*,
             lead(date_effective) over (partition by case_size) as date_end,
             cost_per_wk / 7.0 as cost_per_day
      from storage_rates r
     )
select i.*, sr.total_cost
from invoices i outer apply
     (select sum(datediff(day,
                          (case when i.date_in > sr.date_effective then i.date_in else sr.date_effective end),
                          (case when i.date_out < sr.date_eend then i.date_out else sr.date_end end)
                         ) * sr.cost_per_day
                 ) as total_cost
      from sr
      where i.cs_size = sr.cs_size and  -- I think the case size is relevant
            i.date_in < sr.date_end and
            i.date_out >= sr.date_effective
     ) sr;