连接3个表,总计来自满足特定条件的两列

时间:2014-04-20 21:41:19

标签: mysql sql

说我有3张桌子:

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  |
+------|-------+    +------|-------+

我想将两个表中的总点数相加,按p_ID分组,其中总和大于某个数量,例如1000。所以我希望结果看起来像这样。

Query Result
+------+---------+---------+--------+
| p_id | points1 | points2 | total  |
+------+---------+---------+--------+
| 1    |  1200   |   300   |  1500  |
| 2    |  100    |   900   |  1000  |
| 3    |  1000   |    0    |  1000  |
| 4    |   0     |   1200  |  1200  |
+------|---------+---------+--------+

以下是我当前的查询,但我没有得到我需要的结果。

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

2 个答案:

答案 0 :(得分:2)

为了使其正常工作,您需要在连接之前进行聚合。否则,您最终会遇到与每个游戏的笛卡尔产品相关的问题。

由于MySQL不支持full outer join,最好的方法是使用union all代替:

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;

答案 1 :(得分:0)

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

修改

修正了错误的IFNULL()范围,请参阅SQLfiddle

编辑2

根据@ GordonLinoff的输入修复