如何将上一行的值传递到当前行?

时间:2018-10-12 06:22:16

标签: sql database oracle

如何将上一行的结果传递给当前行的计算

鉴于单位和费用,我需要获取每笔交易的平均费用:

公式:

  1. 平均成本是交易成本之和
  2. 如果“类型”为“子”,则Trx成本等于成本
  3. 如果“类型”为“红色”,则Trx成本为单位*(先前trx成本之和/先前单位之和)
|  Row | Type | Unit | Cost | TrxCost  | Ave_cost |
|  1   |Sub   | 0.2  | 1000 |  1000    | 1000     |
|  2   |Sub   | 0.3  | 2500 |  2500    | 3500     |
|  3   |Sub   | 0.1  | 600  |  600     | 4100     |
|  4   |Red   |- 0.2 |-1100 | -1366.67 | 2733.33  |
|  5   |Sub   | 0.3  | 1000 |  1000    | 3733.33  |
|  6   |Red   | -0.6 | -600 | -3200    | 533.33   |

更新:

订单基于行号。

谢谢。

3 个答案:

答案 0 :(得分:3)

您可以使用递归CTE

WITH cte (row_num,
     type,
     unit,
     sum_of_unit,
     cost,
     trxcost,
     ave_cost
) AS (
     SELECT row_num,
            type,
            unit,
            unit AS sum_of_unit,
            cost,
            cost AS trxcost,
            cost AS ave_cost
     FROM t
     WHERE row_num IN (
          SELECT MIN(row_num)
          FROM t
     )
     UNION ALL
     SELECT t.row_num,
            t.type,
            t.unit,
            c.sum_of_unit + t.unit AS sum_of_unit,
            t.cost,
            CASE t.type
                 WHEN 'Sub'   THEN t.cost
                 WHEN 'Red'   THEN t.unit * ( c.ave_cost / c.sum_of_unit )
            END
       AS trxcost,
            c.ave_cost + CASE t.type
                 WHEN 'Sub'   THEN t.cost
                 WHEN 'Red'   THEN t.unit * ( c.ave_cost / c.sum_of_unit )
            END AS ave_cost
     FROM t
     JOIN cte c ON t.row_num = c.row_num + 1
)
SELECT * FROM cte

Dbfiddle Demo

答案 1 :(得分:1)

您可以分两步进行此操作:一次获得theTrxCost,然后一次获得Ave_cost

顺便说一句,您所说的“平均值”是一个总计。您只是在增加价值。

您需要带有ROWS BETWEEN子句的窗口函数。 (但是,对于SUM(...) OVER (ORDER BY ...),它隐含为BETWEEN UNBOUNDED PRECEDING AND CURRENT。)

select 
  id, type, unit, cost, round(trxcost, 2) as trxcost,
  round(sum(trxcost) over (order by id), 2) as ave_cost
from
(
  select 
    id, type, unit, cost,
    case 
      when type = 'Sub' then cost 
      else
        unit *
        sum(cost) over (order by id rows between unbounded preceding and 1 preceding) /
        sum(unit) over (order by id rows between unbounded preceding and 1 preceding)
    end as trxcost
  from mytable
)
order by id;

我将您的rowid重命名,因为ROW是保留字。

最后一行的结果与您的不同。我使用了您的公式,但是得到了不同的数字。

上个月的演示:https://rextester.com/ASXFY4323

答案 2 :(得分:0)

请参见SQL Window Functions,它使您可以访问结果集中其他行的值。对于您的情况,您需要告诉我们更多何时停止观看等条件:

select
    lag(unit,1) over (partition by type order by whatever) 
  * lag(cost,1) over (partition by type order by whatever)
from Trx

但是我仍然想念您如何将交易和减少量相互关联。必须有一些您没有告诉我们的专栏。如果知道该列(PartNumber?),则可以简单地对其进行分组和求和。