我基本上有三张桌子:
hunt_c_users
hunt_c_collected_eggs
hunt_c_achievements
我正抓住一个排行榜,目前仅使用hunt_c_users
hunt_c_collected_eggs
进行LEFT JOIN,但现在我还需要包含hunt_c_achievements
分。'
目前我的查询是:
SELECT
hunt_c_users.id AS 'id',
CONCAT(first_name, ' ', LEFT(last_name,1), '. From ', city) AS 'user_byline',
fbid AS 'user_fbid',
SUM(hunt_c_collected_eggs.value) AS user_points
FROM hunt_c_users
LEFT JOIN hunt_c_collected_eggs ON hunt_c_users.id = hunt_c_collected_eggs.user_id
WHERE hunt_c_users.id NOT IN ($bannedIDSstr)
GROUP BY hunt_c_users.id
HAVING SUM(hunt_c_collected_eggs.value) > 0
ORDER BY user_points DESC
LIMIT 10
但是当我在hunt_c_achievements
和另一个SUM(hunt_c_achievements.value)
添加另一个LEFT JOIN时,user_points
非常不准确,我理解为什么会发生这种情况(表格是水平加入的,所以成就是添加到每个项目),但我不太明白如何解决它。
这是一个给我不准确结果的查询:
SELECT
hunt_c_users.id AS 'id',
CONCAT(first_name, ' ', LEFT(last_name,1), '. From ', city) AS 'user_byline',
fbid AS 'user_fbid',
SUM(hunt_c_collected_eggs.value) + SUM(hunt_c_achievements.value) AS user_points
FROM hunt_c_users
LEFT JOIN hunt_c_collected_eggs ON hunt_c_users.id = hunt_c_collected_eggs.user_id
LEFT JOIN hunt_c_achievements ON hunt_c_users.id = hunt_c_achievements.user_id
WHERE hunt_c_users.id NOT IN ($bannedIDSstr)
GROUP BY hunt_c_users.id
HAVING SUM(hunt_c_collected_eggs.value) > 0
ORDER BY user_points DESC
LIMIT 10
<小时/> 的更新
我在这里添加了一个SQL小提琴:http://sqlfiddle.com/#!2/ac1f69/1
使用提供的虚拟数据我的预期结果是:
id | user_byline | user_fbid | user_points
------------------------------------------
1033 | ... | ... | 111
1030 | ... | ... | 97
1031 | ... | ... | 62
1032 | ... | ... | 27
答案 0 :(得分:2)
您必须使用子查询分别计算总和:
SET @bannedIDSstr = 0;
SELECT
user.id AS 'id',
CONCAT(user.first_name, ' ', LEFT(user.last_name, 1), '. From ', user.city) AS 'user_byline',
user.fbid AS 'user_fbid',
IFNULL(eggs_sum.collected_eggs, 0) + IFNULL(achievement_sum.achievement, 0) AS user_points
FROM hunt_c_users AS user
LEFT JOIN
(SELECT
eggs.user_id,
SUM(eggs.value) AS collected_eggs
FROM hunt_c_collected_eggs AS eggs
GROUP BY eggs.user_id
HAVING collected_eggs > 0
) AS eggs_sum
ON user.id = eggs_sum.user_id
LEFT JOIN
(SELECT
achievements.user_id,
SUM(achievements.value) AS achievement
FROM hunt_c_achievements AS achievements
GROUP BY achievements.user_id
) AS achievement_sum
ON user.id = achievement_sum.user_id
WHERE user.id NOT IN (@bannedIDSstr)
GROUP BY user.id
ORDER BY user_points DESC
LIMIT 10;
DEMO @ SQL Fiddle