我试图通过一个查询从2个不同的表中计算2个不同的东西。
我的问题是我的其中一个联接会影响其他联接计数。
我想要计算每个连接,而不与其他连接的计数有任何连接。
以下是查询:
SELECT score.score, u.user_name,
COUNT(mrank.user_id) as rank, COUNT(cr.id) as completedChallenges
FROM user u
LEFT OUTER JOIN challenges_score_user_rel score
ON score.user_id = u.id AND score.challenge_group_id = 0
LEFT OUTER JOIN challenges_score_user_rel mrank
ON mrank.score >= score.score AND mrank.challenge_group_id = 0 AND (SELECT forGym.gym
FROM user forGym WHERE forGym.id = mrank.user_id) = 22
LEFT OUTER JOIN challenges_requests cr
ON u.id = cr.receiver AND cr.status = 3
WHERE u.gym = 22 AND score.score IS NOT NULL GROUP BY u.id ORDER BY score.score DESC LIMIT 20
+------------------+------+---------------------+
| score| user_name | rank | completedChallenges |
+------------------+------+---------------------+
| 999 | A | 3 | 3 |
+------------------+----------------------------+
| 155 | B | 2 | 0 |
+------------------+----------------------------+
| 130 | C | 3 | 0 |
+------------------+----------------------------+
| 24 | D | 4 | 0 |
+------------------+----------------------------+
从结果中我可以看出,用户A排在第一位,但排名第3位。
排名应该是按分数排序的数字。
排名的计数来自此加入:
LEFT OUTER JOIN challenge_score_user_rel mrank
ON mrank.score >= score.score AND mrank.challenge_group_id = 0 AND (SELECT forGym.gym
FROM user forGym WHERE forGym.id = mrank.user_id) = 22
如果我删除此联接:
LEFT OUTER JOIN challenges_requests cr
ON u.id = cr.receiver AND cr.status = 3
计数很好,我得到了所有用户的正确排名。
为什么2个联接会相互影响,我可以依靠它们自己计算吗?
答案 0 :(得分:1)
解决此问题的最简单方法是使用count(distinct)
:
SELECT score.score, u.user_name,
COUNT(distinct mrank.user_id) as rank,
COUNT(distinct cr.id) as completedChallenges
问题是您正在为每个用户获取笛卡尔积。如果数字很大,那么这不是性能最佳的解决方案。在这种情况下,您希望预先聚合from
子句中的数据,或者使用SELECT
子句中的相关子查询。