2014-04-01 182 views
1

我有三個表主要有:MySQL的SUM + SUM

hunt_c_users hunt_c_collected_eggs hunt_c_achievements

我抓住目前只使用hunt_c_users用左排行榜JOIN上hunt_c_collected_eggs但現在我需要包括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 

但是,當我在另一個LEFT添加JOIN上hunt_c_achievements和另一SUM(hunt_c_achievements.value)user_points是非常不準確的,我明白了爲什麼這是發生(表是如此的成就水平加盟被添加到每個項目),但我不太明白如何解決它。

這是給我的結果不準確的查詢:使用虛擬http://sqlfiddle.com/#!2/ac1f69/1

我預期的結果:

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 


UPDATE

我在這裏增加了一個SQL小提琴 - 提供的數據爲:

id | user_byline | user_fbid | user_points 
------------------------------------------ 
1033 | ...   | ...  | 111 
1030 | ...   | ...  | 97 
1031 | ...   | ...  | 62 
1032 | ...   | ...  | 27 
+0

可以爲用戶提供表大綱的SQL小提琴,這樣我就可以運行一些測試?你能張貼一張預期結果的表嗎? – citizen404

+0

@ mind-404 http://sqlfiddle.com/#!2/71a47 - 注意表名稍有改動。 – ahren

+0

@ mind-404 - http://sqlfiddle.com/#!2/ac1f69/1已經更新了一些'anonymized'數據 - 至於'$ bannerIDSstr',你可以用'0'替換它 - 它不包括某些'hunt_c_users.id'來自排行榜 – ahren

回答

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