I would like to ask how to use the FIFO method with MySQL 8 to generate the expected result as follow.
product_id | type | quantity | price | operation_date |
---|---|---|---|---|
1 | PURCHASE | 10 | 100 | 2024-08-01 |
2 | PURCHASE | 25 | 80 | 2024-08-02 |
2 | SALE | 20 | 140 | 2024-08-03 |
1 | SALE | 7 | 120 | 2024-08-03 |
2 | PURCHASE | 20 | 90 | 2024-08-04 |
3 | PURCHASE | 40 | 50 | 2024-08-05 |
3 | PURCHASE | 20 | 40 | 2024-08-06 |
3 | PURCHASE | 20 | 20 | 2024-08-07 |
2 | SALE | 20 | 160 | 2024-08-07 |
3 | SALE | 50 | 150 | 2024-08-07 |
3 | SALE | 20 | 160 | 2024-08-08 |
1 | PURCHASE | 10 | 80 | 2024-08-09 |
I need to calculate stock value for each product.
Expected Output
product_id | Stock Value |
---|---|
1 | 1100 |
2 | 450 |
3 | 200 |
To accurately calculate the current stock value, we need to use the First-In-First-Out (FIFO) method. The FIFO method means that the items bought first are sold first, so the remaining stock should be valued at the most recent purchase prices.
I have tried many queries but I am not getting what I am looking for.
Stock Value Calculation Example for Product Id 1 (manual calculation)
Purchase 10 qty at price 100 on 2024-08-01 so that stock value is 1000
after 2024-08-01, I sold 7 qty at 120 so now my stock value will be 300 as the purchase price was 100.
On 2024-08-09 I purchased another 10 qty at 80.
Now the final stock value for me is:
3 qty @ 100 = 300 (left from a previous purchase)
10 qty @ 80 = 800
-------------------
13 qty = 1100 stock value
Stock Value Calculation Example for Product Id 2 (manual calculation)
Purchase 25 qty at price 80
Sell 20 qty at
---------------------------
5 qty remaining from first purchase at 80 price
Purchase 20 qty at price 90
---------------------------
Total 25 qty (5 qty @ 80 price and 20 qty @ 90 price)
Sell 20 qty (using fifo method 5 deduct from first purchase and 15 deduct from second purchase)
---------------------------
Remaining 5 qty @ 90 price
So, the stock value is 5 * 90 = 450
Stock Value Calculation Example for Product Id 3 (manual calculation)
Purchase 40 qty at price 50
Purchase 20 qty at price 40
Purchase 20 qty at price 20
----------------------------
- 50 qty (sell)
----------------------------
Remaining 30 qty (using FIFO 10 qty left at 40 price and 20 left at 20 price
----------------------------
- 20 qty (sell)
----------------------------
Remaining 10 qty (using FIFO 10 qty left at 20 price)
So, stock value is 10 qty * 20 price = 200
NOTE: IF CHANGING THE STRUCTURE OF TABLE CAN HELP IN SOLVING THIS
PROBLEM THEN ALSO SUGGEST.
2
Answers
Here is the query to calculate the stock value for each product using FIFO:
The recursive common table expression (inventory_cte) processes purchases and sales. For each sale, it calculates the remaining quantities and the cost of the remaining inventory.
Summarize the stock values by summing up the total cost for each product where remaining quantity is greater than zero.
dbfiddle
So the best approach might be using
CTE_Operations
: creating a CTE (CTE_Operations) that adjusts the quantity based on whether the operation is a SALE or PURCHASE. For sales, the quantity is negated to reflect stock reduction. See docs for referenceCTE_RunningStock:
CTE calculates the running stock for each product. usually with a window function to accumulate the stock after each transaction(SUM(adjusted_quantity) OVER (...)).
Finally
CTE_StockAfterSales
calculates the remaining stock after sales have been applied.Here is a code snippet: