Reputation: 1
Say I have 3 tables:
Players +------+-------+ | id | name | +------+-------+ | 1 | Ben | | 2 | Bill | | 3 | John | | 4 | Hugh | | 5 | Fred | +------|-------+
Game1 Game2 +------+-------+ +------+-------+ | p_id | points| | p_id | points| +------+-------+ +------+-------+ | 1 | 800 | | 1 | 300 | | 1 | 400 | | 5 | 800 | | 2 | 100 | | 2 | 900 | | 3 | 1000 | | 4 | 1200 | +------|-------+ +------|-------+
I want to sum the total of points from both tables, grouped by p_ID where the sum is greater than a certain amount, 1000 for example. So i would want the result to look like this.
Query Result +------+---------+---------+--------+ | p_id | points1 | points2 | total | +------+---------+---------+--------+ | 1 | 1200 | 300 | 1500 | | 2 | 100 | 900 | 1000 | | 3 | 1000 | 0 | 1000 | | 4 | 0 | 1200 | 1200 | +------|---------+---------+--------+
Below is my current query but I'm not getting the results I need.
SELECT `players`.`p_id`,
COALESCE(sum(`Game1`.`points`), 0) as 'Game1',
COALESCE(sum(`Game2`.`points`), 0) as 'Game_2',
COALESCE(sum(`Game1`.`points`), 0) + COALESCE(sum(`Game2`.`points`), 0) as 'total'
from `players`
left join `Game1` on `players`.`p_id`=`Game1`.`p_id`
left join `Game2` on `players`.`p_id`=`Game2`.`p_id`
having sum(`Game2`.`points`) + sum(`Game1`.`points`) >= 1000
order by sum(`Game1`.`points`) +
sum(`Game2`.`points`) desc
Upvotes: 0
Views: 65
Reputation: 65274
SELECT
players.id AS p_id,
IFNULL(points1,0) AS Game1,
IFNULL(points2,0) AS Game2,
IFNULL(points1,0)+IFNULL(points2,0) AS total
FROM players
LEFT JOIN (
SELECT p_id, SUM(Game1.points) AS points1
FROM Game1
GROUP BY p_id
) AS GameSum1 ON players.id=GameSum1.p_id
LEFT JOIN (
SELECT p_id, SUM(Game2.points) AS points2
FROM Game2
GROUP BY p_id
) AS GameSum2 ON players.id=GameSum2.p_id
GROUP BY players.id
HAVING total>=1000
ORDER BY total DESC
EDIT
Fixed wrong IFNULL()
scope, see SQLfiddle
EDIT 2
Fixed according to @GordonLinoff's input
Upvotes: 0
Reputation: 1269643
In order for this to work correctly, you need to do the aggregation before the join. Otherwise, you end up with issues related to a cartesian product for each game.
Because MySQL does not support full outer join
, the best way is to use union all
instead:
select p_id, sum(points1) as points1, sum(points2) as points2
from ((select p_id, points as points1, 0 as points2
from Game1
) union all
(select p_id, 0, points
from Game2
)
) g
group by p_id;
Upvotes: 2