There are 3 tables, A
, B
, C
.
Table A
has an id
column, and B
& C
integer column which represents money and a_id
which reference id in table A
.
Below is an example of table A, B, C
table A
id |
---|
1 |
2 |
3 |
table B
id | a_id | money |
---|---|---|
1 | 1 | 1000 |
2 | 1 | 2000 |
3 | 2 | 3500 |
tableC
id | a_id | money |
---|---|---|
1 | 1 | 100 |
2 | 2 | 200 |
3 | 2 | 400 |
In this case, I wanna aggregate them like one of these.
a_id | B_money_sum | C_money_sum |
---|---|---|
1 | 2000 | 100 |
2 | 3500 | 600 |
or
a_id | money_sum |
---|---|
1 | 2100 |
2 | 4100 |
I’ve tries this, but the result wasn’t expected one.
(aggregation was based on cartesian product)
select a_id, sum(b.money) B_money_sum, sum(c.money) C_money_sum
from A
join B on A.id = B.a_id
join C on A.id = C.a_id
group by a_id
Isn’t it possible only join, without subquery ?
2
Answers
No, because when there is more than one a_id (TableB and TableC) per id(TableA) that made a one-to-many join, which creates more rows (essentially, a duplication of rows, also known as "Relational Multiplication").
A common approach to fix that issue is to isolate the SUM() in a separate query , subquery
https://dbfiddle.uk/coZvQsuT
This is a bit trickier if table b has an id which c doesn’t or vice versa. Let’s take this case for example.
In this case, b has id 4 while c has id 3. If we use an inner join, both id 3 and id 4 will have their data missing in the result set:
However, if we use a one-sided outer join , we will still have some data missing on the other side.
In order to bridge the gap for all sides, a full join is required. But since MySQL has yet to implement a full join, a UNION is called for to combine the two outer joins.
Note: The outmost layer is required to use the ORDER BY clause, which is ineffective in UNION.