Reputation: 7533
I have created a SQLfiddle demo with sample data and desired result here :(http://sqlfiddle.com/#!9/dfe73a/7)
sample data
-- table company
+--------+---------+
| id | name |
+--------+---------+
| 1 | foo |
| 2 | bar |
+--------+---------+
-- table sales
+--------+---------------+-----------------+
| id | company_id | total_amount |
+--------+---------------+-----------------+
| 1 | 1 | 300.0 |
| 2 | 1 | 300.0 |
| 2 | 1 | 100.0 |
+--------+---------------+-----------------+
-- table moves
+--------+---------------+-----------------+
| id | company_id | balance_move |
+--------+---------------+-----------------+
| 1 | 1 | 700.0 |
| 2 | 1 | -300.0 |
| 2 | 1 | -300.0 |
+--------+---------------+-----------------+
I need to select every company along with the sum of it's total amount of sales and the sum of it's total balance moves
desired result
+----+----------------------+---------------------+
| id | total_amount_sum | balance_move_sum |
+----+----------------------+---------------------+
| 1 | 700 | 100 |
+----+----------------------+---------------------+
| 2 | (null) | (null) |
+----+----------------------+---------------------+
I tried this SQL query
SELECT
company.id,
sum(total_amount) total_amount_sum,
sum(balance_move) balance_move_sum
FROM company
LEFT JOIN sales ON company.id = sales.company_id
LEFT JOIN moves ON company.id = moves.company_id
GROUP BY company.id
But the sum()
functions add all the redundant values came from the joins which result in 2100 (700*3)
for total amount and 300 (100*3)
for net balance
bad SQL statement result
+----+----------------------+---------------------+
| id | total_amount_sum | balance_move_sum |
+----+----------------------+---------------------+
| 1 | 2100 | 300 |
+----+----------------------+---------------------+
| 2 | (null) | (null) |
+----+----------------------+---------------------+
Is it possible to achieve the result I want ?
Upvotes: 2
Views: 158
Reputation: 10297
You're repeating rows by doing your joins.
Company: 1 row per company
After Sales join: 3 rows per company (1x3)
After Moves join: 9 rows per company (3x3)
You end up triplicating your SUM
because of this.
One way to fix is to use derived tables like this, which calculate the SUM
first, then join the resulting rows 1-to-1.
SELECT
company.id,
total_amount_sum,
balance_move_sum
FROM company
LEFT JOIN (SELECT SUM(total_amount) total_amount_sum, company_id
FROM sales
GROUP BY company_id
) sales ON company.id = sales.company_id
LEFT JOIN (SELECT SUM(balance_move) balance_move_sum, company_id
FROM moves
GROUP BY company_id
) moves ON company.id = moves.company_id
Upvotes: 1
Reputation: 4251
Using sub-queries to calculate the two sums separately will work.
SELECT
company.id,
(Select sum(total_amount) from sales where sales.company_id = company.id) total_amount_sum,
(Select sum(balance_move) from moves where moves.company_id = company.id) balance_move_sum
FROM company
Upvotes: 0