Reputation: 888
i'm trying to do LEFT JOIN with SUM and Arithmetic Operators of 3 tables, and i'm stuck,
In the expected result in the bottom below, there is new field called initial_stock
which is the result of:
initial_stock
= current_stock
+ sum(used)
- sum(restock_amount)
You can try in in here: https://dbfiddle.uk/?rdbms=postgres_12&fiddle=2216e64ee6fa90556d8f952f115dd070
Heres the tables:
product
table:
id product_name current_stock
------ ------------ -------------
1 abc 10
2 aaa 0
3 bbb 10
4 ddd 20
usage
table:
id product_id used date_out
------ ------------ ------- ----------
1 1 10 2020-11-20
2 1 20 2020-11-20
3 2 20 2020-11-11
product_restock
table:
id product_id restock_amount date_in
------ ------------ -------------- -----------
1 1 10 2020-11-15
2 1 20 2020-11-14
3 4 10 2020-11-09
Expected result from date 2020-11-01
to 2020-11-30
:
id product_name initial_stock restock used current_stock
------ ------------ ------------- ------- ---- -------------
1 abc 10 30 30 10
2 aaa 20 0 20 0
3 bbb 10 0 0 10
4 ddd 10 10 0 20
Upvotes: 1
Views: 1154
Reputation: 164089
Aggregate in usage
and product_restock
separately and then join to product
:
select p.id, p.product_name,
p.current_stock + coalesce(u.used, 0) - coalesce(r.restock, 0) initial_stock,
coalesce(r.restock, 0) restock,
coalesce(u.used, 0) used,
p.current_stock
from product p
left join (select product_id, sum(used) used from usage where date_out between '2020-11-01' and '2020-11-30' group by product_id) u
on u.product_id = p.id
left join (select product_id, sum(restock_amount) restock from product_restock where date_in between '2020-11-01' and '2020-11-30' group by product_id) r
on r.product_id = p.id
See the demo.
Results:
> id | product_name | initial_stock | restock | used | current_stock
> -: | :----------- | ------------: | ------: | ---: | ------------:
> 1 | abc | 10 | 30 | 30 | 10
> 2 | aaa | 20 | 0 | 20 | 0
> 3 | bbb | 10 | 0 | 0 | 10
> 4 | ddd | 10 | 10 | 0 | 20
Upvotes: 2
Reputation: 222462
You can can use lateral joins for this:
select p.*, u.used, pr.restock_amount,
p.current_stock + u.used - pr.restock_amount as initial_stock
from product p
cross join lateral (
select coalesce(sum(u.used), 0) as used
from usage u
where u.product_id = p.id and u.date_out between '2020-11-01'::date and '2020-11-30'::date
) u
cross join lateral (
select coalesce(sum(u.restock_amount), 0) as restock_amount
from product_restock pr
where pr.product_id = p.id and pr.date_out between '2020-11-01'::date and '2020-11-30'::date
) pr
Upvotes: 0