Reputation: 57
How can I pass the result of previous row to the computation of the current row
Given the unit and the cost, I need to get the average cost of each transactions:
The formula:
| 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 |
Update:
Order is based on row number.
Thanks.
Upvotes: 0
Views: 907
Reputation: 31676
You may use Recursive 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
Upvotes: 3
Reputation: 95052
You can do this in two passes: one to get theTrxCost
, then one to get the Ave_cost
.
What you are calling "average" is a running total by the way; you are merely adding up values.
You need window functions with ROWS BETWEEN
clauses. (In case of SUM(...) OVER (ORDER BY ...)
this is implicitly BETWEEN UNBOUNDED PRECEDING AND CURRENT
, however).
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;
I renamed your row
column id
, because ROW
is a reserved word.
The last row's results differ from yours. I used your formula, but get different figures.
Rextester demo: https://rextester.com/ASXFY4323
Upvotes: 1
Reputation: 3925
See the SQL Window Functions , which allow you to access values from other rows in the result set. In your case, you will need to tell us some more criteria for when to stop looking etc.:
select
lag(unit,1) over (partition by type order by whatever)
* lag(cost,1) over (partition by type order by whatever)
from Trx
But I'm still missing how you want to correlate the transactions and the reductions to each other. There must be some column you're not telling us about. If that column (PartNumber?) is known, you can simply group by and sum by that.
Upvotes: 0