I am a beginner trying to build very simple inventory system using PHP + SQL
I have 2 warehouse. I added 2 tables, 1 for each warehouse contains (item id)-(in)- (out) like shown below
table1
| item id | in | out |
|---|---|---|
| item1 | 10 | 0 |
| item1 | 5 | 0 |
| item2 | 0 | 3 |
| item2 | 0 | 2 |
table2
| item id | in | out |
|---|---|---|
| item1 | 12 | 0 |
| item1 | 50 | 0 |
| item2 | 0 | 10 |
| item2 | 0 | 30 |
I have report show balance for each warehouse separately by using query below
Select item_id, sum(in-out) as balance
from table1
group by item_id
like below
| item id | balance |
|---|---|
| item1 | 2 |
| item2 | 20 |
My question is how show each warehouse balance in one table like below
| item id | warehouse1 | warehouse2 |
|---|---|---|
| item1 | 7 | 2 |
| item2 | 3 | 20 |
I tired with this query but I get wrong results
SELECT table1.item_id,
sum(table1.in) - sum(table1.out) as tb1,
sum(table2.in) - sum(table2.out) as tb2
FROM table1,
table2
WHERE table1.item_id = table2.item_id
GROUP by item_id
the query above have 2 problems
- results are not correct
- only items in both tables are shown , while any item exist in table and not exists in the second one is not shown
Just calculate the sum (like you did for your first table) for both tables, then join the results together on item_id.
If you can guarantee that both warehouses will have the exact same unique list of item_ids then you can do an INNER JOIN. I've assumed that they may have some discrepancies, so I've opted for a FULL JOIN. However, It seems that MySQL doesn't support the FULL JOIN option. So I've taken the UNION of the LEFT JOIN and the RIGHT JOIN to achieve the desired result.
I've quoted the IN and OUT columns with backticks, as IN is a SQL keyword (not sure about OUT, best to be safe). That way they will be treated as column names and not whatever else they mean (i.e. IN is an operator).
First, setup some tables to mimic your data.
Secondly, perform the aggregations and join the results.
I have deliberately used UNION instead of UNION ALL as both the LEFT JOIN and the RIGHT JOIN will contain the INNER JOIN. So we don't want to include the INNER JOIN twice.
Try it yourself: db<>fiddle