CREATE TABLE inventory (
id SERIAL PRIMARY KEY,
stock_date DATE,
product VARCHAR,
stock_balance INT
);
INSERT INTO inventory
(stock_date, product, stock_balance
)
VALUES
('2025-10-01','prod_01','100'),
('2025-10-01','prod_02','500'),
('2025-10-31','prod_01','800'),
('2025-10-31','prod_02','600'),
('2025-10-31','prod_03','700'),
('2025-10-31','prod_04','400');
Expected Result:
product | stock_date | stock_balance | change |
---------|--------------|----------------|-----------|-
prod_01 | 2025-10-01 | 100 | 700 |
prod_01 | 2025-10-31 | 800 | 700 |
prod_02 | 2025-10-01 | 500 | 100 |
prod_02 | 2025-10-31 | 600 | 100 |
prod_03 | 2025-10-01 | 0 | 400 |
prod_03 | 2025-10-31 | 400 | 400 |
prod_04 | 2025-10-01 | 0 | 700 |
prod_04 | 2025-10-31 | 700 | 700 |
I want to display for each product in the table the stock_balance on 2025-10-01 and 2025-10-31 and calculate the change of the stock_balance between these two dates in a separate column.
So for I have been able to develop this query:
select
t1.product as product,
t1.stock_date as stock_date,
t1.stock_balance as stock_balance,
LAST_VALUE(t1.stock_balance) OVER (PARTITION BY t1.product ORDER BY stock_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) -
FIRST_VALUE(t1.stock_balance) OVER (PARTITION BY t1.product ORDER BY stock_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as change
from
(select
product as product,
stock_date as stock_date,
sum(stock_balance) as stock_balance
from inventory
group by 1,2
order by 1,2 desc) t1
group by 1,2,3
order by 1,2,3;
The query provides the result correctly for prod_01 and prod_02.
However, for prod_03 and prod_04 it is not correct. I assume this is because they appear only on stock_date = 2025-10-31.
How do I need to modify the query to also get these products displayed as in the expected results?
(I guess somehow I need to insert an empty row for these products for stock_date = 2025-10-01)