Home > other >  MySQL - How To query a table result that involves preceding calculated values
MySQL - How To query a table result that involves preceding calculated values

Time:12-14

Say i have a table items sorted ascending by date

date item quantity cost
2022-12-01 Pencil 12 10.00
2022-12-02 Pencil 10 10.00
2022-12-04 Pencil 5 10.00
2022-12-06 Eraser 10 4.00
2022-12-10 Eraser 50 4.00
2022-12-15 Eraser 25 4.00

I need to write an SQL query that returns a calculated field called calculated_cost, where the expression is simply quantity * cost

Then I will need to increment calculated_cost for every row and save it to a field called accumulated_cost

However here is the challenge, I am also required to store a field called previous_accumulated_cost where it takes the preceding accumulated_cost and store it as a value.

Note that I also need to calculate these by partitioning based on item and order by date, means i need to reset the accumulated_cost and previous_accumulated_cost when I reach a new item.

Basically i need to generate an output like this.

date item quantity cost calculated_cost accumulated_cost previous_accumulated_cost
2022-12-01 Pencil 12 10.00 120.00 120.00 0.00
2022-12-02 Pencil 10 10.00 100.00 220.00 120.00
2022-12-04 Pencil 5 10.00 50.00 270.00 220.00
2022-12-06 Eraser 10 4.00 40.00 40.00 0.00
2022-12-10 Eraser 50 4.00 200.00 240.00 40.00
2022-12-15 Eraser 25 4.00 100.00 340.00 240.00

I have already tried an SQL query like this

SELECT *,
   (i.quantity * i.cost) AS calculated_cost,
   SUM(i.quantity * i.cost) OVER (PARTITION BY i.item ORDER BY i.date) AS accumulated_cost,
   IFNULL(LAG(i2.accumulated_cost) OVER (PARTITION BY i.item ORDER BY i.date), 0) AS previous_accumulated_cost
FROM items i
LEFT JOIN (
   SELECT item, SUM(quantity * cost) OVER (PARTITION BY item ORDER BY date) AS accumulated_cost
   FROM items 
) i2 ON i.item = i2.item

However this doesn't work, as the number of item entries can keep increasing and I am not sure how to keep referencing back the previous_accumulated_cost

Would appreciate some help. Thanks!

CodePudding user response:

Your hunch to use analytic functions was spot on. I would suggest using this version:

SELECT
    quantity * cost AS calculated_cost,
    SUM(quantity * cost) OVER (PARTITION BY item ORDER BY date) AS accumulated_cost,
    SUM(quantity * cost) OVER (PARTITION BY item ORDER BY date) - (quantity * cost) AS previous_accumulated_cost
FROM items
ORDER BY item, date;

Appreciate that the previous_accumulated_cost is simply the accumulated_cost minus the calculated_cost.

  • Related