Oracle累计总和基于使用事务

时间:2015-11-12 18:55:07

标签: sql oracle sum cumulative-sum

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

示例:

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

frombody

这就是我的结果与上述信息的关系

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

正如您所注意到的,结果会将累积总和停止在8,并显示应该的LastUsageDate。但是,当它运行累积总和时,如果它使得总和大于OrderQty的数字,它不包括它,那么该部分被排除在结果之外,尽管事实已经被完全使用了。 / p>

这是一个例子。

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

如果这是该部件的数据,则不会有任何结果,因为从11月10日到10月12日,累计金额从6到9不等。

即使总和大于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

这是SQL:

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

WHERE子句限制了总结的数据,但如果它没有将cum_sum放在OrderQty上,它将只包含下一个数字。我不知道如何改变它以包括下一条记录,即使它确实高于OrderQty。

1 个答案:

答案 0 :(得分:0)

喜欢这个吗?

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