基于使用交易的 Oracle 累计总和

Oracle cumulative sum based on usage transactions

我需要根据该值匹配或仅比它应匹配的列高一个记录值的条件来累加一个值。我正在制作一个系统来跟踪订购的零件数量是否已完全使用。由于您可以在一个订单中订购多个数量,并且一次使用少量,所以我需要知道订购数量何时被使用。

示例:

子查询显示每个部分的使用事务

OrderNumber | PartNumber | OrderQty | LastUsageDate | Usage
j55789      |  ks568     |  8       |    10 - oct   |  2
j55789      |  ks568     |  8       |    11 - oct   |  2
j55789      |  ks568     |  8       |    11 - oct   |  2
j55789      |  ks568     |  8       |    12 - oct   |  2
j55789      |  ks568     |  8       |    13 - oct   |  2

这就是我根据上述信息得出的结果

OrderNumber | PartNumber | OrderQty | LastUsageDate | Usage
j55789      |  ks568     |  8       |    12 - oct   |  8

正如您所注意到的,结果在 8 处停止了累积总和,并显示了它应该显示的 LastUsageDate。但是,虽然它是 运行 累计总和,但如果它涉及到一个会使总和大于 OrderQty 的数字,它不包括它,尽管事实上已经被排除在结果之外完全使用。

这是一个例子。

OrderNumber | PartNumber | OrderQty | LastUsageDate | Usage
j55789      |  ks568     |  8       |    10 - oct   |  2
j55789      |  ks568     |  8       |    11 - oct   |  2
j55789      |  ks568     |  8       |    11 - oct   |  2
j55789      |  ks568     |  8       |    12 - oct   |  3
j55789      |  ks568     |  8       |    13 - oct   |  2

如果这是零件的数据,它不会有任何结果,因为从 10 月 11 日到 12 日的累计总和从 6 到 9。

我需要一种方法让累计总和包括记录,即使总和会大于 OrderQty,但它也需要停止计数超过该记录。所以我的结果应该是。

OrderNumber | PartNumber | OrderQty | LastUsageDate | Usage
j55789      |  ks568     |  8       |    12 - oct   |  9

这里是 SQL:

    SELECT d1.* FROM(

    SELECT c1.*, max(c1.LastGiDate) LastGiDate, max(c1.cum_sum) GIQty  FROM(

    SELECT b1.*, SUM(b1.GiQty) OVER (PARTITION BY b1.MRNum, b1.PartNo ORDER BY b1.LastGiDate) cum_sum FROM(***subquery here***) c1

    WHERE c1.cum_sum <= c1.OrderQty

    GROUP BY ***c1 fields***) d1

    WHERE d1.GIQty >= d1.OrderQty;

WHERE 子句限制了汇总的数据,但如果不将 cum_sum 放在 OrderQty 上,它只会包含下一个数字。我不确定如何更改它以包括下一条记录,即使它确实超过了 OrderQty。

像这样?

with d as (
-- Test Data
SELECT 'j55789' order_Number, 'ks568' part_Number,  8 order_qty, to_date('10-OCT-2015') last_usage_date, 2 usage FROM DUAL union all 
SELECT 'j55789' order_Number, 'ks568' part_Number,  8 order_qty, to_date('11-OCT-2015') last_usage_date, 2 usage FROM DUAL union all 
SELECT 'j55789' order_Number, 'ks568' part_Number,  8 order_qty, to_date('11-OCT-2015') last_usage_date, 2 usage FROM DUAL union all 
SELECT 'j55789' order_Number, 'ks568' part_Number,  8 order_qty, to_date('12-OCT-2015') last_usage_date, 3 usage FROM DUAL union all 
SELECT 'j55789' order_Number, 'ks568' part_Number,  8 order_qty, to_date('13-OCT-2015') last_usage_date, 2 usage FROM DUAL ),
-- Step 1: Get the running sum for each record 
step1 as ( SELECT d.*, sum(usage) over ( partition by order_number, part_number order by last_usage_date) running_sum FROM d ),
-- Step 2: Filter our records that started out beyond our order_qty
step2 as ( SELECT step1.*, row_Number() over ( partition by order_number, part_number order by running_sum desc ) rn from step1 WHERE running_sum - usage < order_qty )
-- Report on the last unfiltered record in the group 
select order_Number, part_number, order_qty, last_usage_date, running_sum usage from step2 where rn = 1