与GROUP BY一起执行JOINS和CONDITIONS时复制COUNT

时间:2016-07-02 17:34:58

标签: mysql

我有以下两个表

游戏

+--------+-------------+----------------+----------------+
| gameID | challengeID | player1_userID | player2_userID |
+--------+-------------+----------------+----------------+
|      1 |           1 |              1 |              2 |
|      2 |           1 |              1 |              3 |
|      3 |           2 |              1 |              4 |
+--------+-------------+----------------+----------------+

挑战

+-------------+---------+
| challengeID | content |
+-------------+---------+
|           1 | one     |
|           2 | two     |
|           3 | three   |
+-------------+---------+

我希望输出如下。基本上,用户(例如,userID = 1)想要所有挑战的数据以及针对每个挑战所玩的游戏的数量,以及关于请求用户是否已经玩过该挑战的信息。

输出(对于userID = 1)

+-------------+---------+---------+---------------------+
| challengeID | content | n_games | played_by_requestor |
+-------------+---------+---------+---------------------+
|           1 | one     |       2 | TRUE                |
|           2 | two     |       1 | TRUE                |
|           3 | three   |       0 | FALSE               |
+-------------+---------+---------+---------------------+

这似乎看似简单,但我在过去的4个小时(现在是凌晨1点35分)一直在尝试它,我能得到的最好的是下面的代码。

SET @myID = 1;
SELECT
    COUNT(g1.challengeID) as n_games,
    CASE
        WHEN g.gameID IS NULL THEN FALSE ELSE TRUE
    END AS played_by_requestor,
    c.*
FROM challenges c
LEFT JOIN games g
    ON  c.challengeID = g.challengeID AND 
        (player1_userID = @myID or player2_userID = @myID)
LEFT JOIN games g1
    ON c.challengeID = g1.challengeID
GROUP BY c.challengeID;

但它给出了错误的结果。对于requestor userID = 1,此代码为challengeID = 1提供n_games = 4,对于challengeID = 2提供n_games = 1。

SQL Fiddle here

感谢。

1 个答案:

答案 0 :(得分:1)

最后,让它发挥作用!

SET @myID = 3;
SELECT  
    COUNT(g.challengeID) AS n_games, 
    CASE 
        WHEN uC.p_challengeID IS NULL THEN FALSE ELSE TRUE
    END AS played_by_requestor, 
    c.*
FROM challenges c
LEFT JOIN games g
    ON (c.challengeID = g.challengeID)
LEFT JOIN
    (SELECT g1.challengeID AS p_challengeID
    FROM games g1
    WHERE (player1_userID = @myID OR player2_userID = @myID)
    GROUP BY g1.challengeID) uC
ON c.challengeID = uC.p_challengeID
GROUP BY c.challengeID;

如果有一个更优雅的解决方案(例如,在games表上没有使用两个联接),我很乐意接受它作为答案。