MySQL SUM + SUM

时间:2014-04-01 22:11:17

标签: mysql

我基本上有三张桌子:

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

1 个答案:

答案 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