2012-07-05 115 views
0

我有以下SQL查詢。MYSQL SUM和substract

SELECT u.username, SUM(p.points) AS points, 
      SUM(sp.spPoints) AS spPoints, 
      (SUM(sp.spPoints) - SUM(p.points)) AS Puntos_Restantes 
FROM  users as u 
LEFT JOIN points as p ON (u.userid = p.userid) 
LEFT JOIN sppoints AS sp ON (u.userid = sp.userid) 
WHERE  u.userid = '1' 
GROUP BY u.userid 

我的目標是要總結2場,然後減去他們,但是當我執行上面的查詢,第二SUM是錯誤的。
表是這樣的:

points: pointId, userId, points  
sppoints: spPointId, userId, spPoints  

在點我有這樣的量:25和spPoints:10 但是當我運行查詢,我得到:

points spPoints Puntos_Restantes 
25  30    5 

這是怎麼回事錯在這裏?

+0

你可以顯示你正在拉的桌子嗎?或者它太大? – Dancrumb 2012-07-05 13:58:16

+0

也許你的意思是總和((sp.spPoints) - (p.points)) – xQbert 2012-07-05 13:58:51

+0

請顯示重現你的例子所需的全部數據。 – lanzz 2012-07-05 13:58:52

回答

2

users與其他兩個表格有一對多的關係。這會導致2個連接生成一個迷你Carstesian產品,並在points列中生成具有相同數據的多行 - 然後進行彙總。

您可以通過使用子查詢組,然後加入,以避免這個問題:

SELECT 
     u.username 
    , COALESCE(p.pPoints,0) 
     AS pPoints 
    , COALESCE(sp.spPoints,0) 
     AS spPoints 
    , COALESCE(p.pPoints,0) - COALESCE(sp.spPoints,0) 
     AS Puntos_Restantes 
FROM 
     users as u 
    LEFT JOIN 
     (SELECT userid, SUM(points) AS pPoints 
     FROM points 
     WHERE userid = 1 
     GROUP BY userid 
    ) AS p 
    ON u.userid = p.userid 
    LEFT JOIN 
     (SELECT userid, SUM(spPoints) AS spPoints 
     FROM sppoints 
     WHERE userid = 1 
     GROUP BY userid 
    ) AS sp 
    ON u.userid = sp.userid 
WHERE u.userid = 1 ; 

如果你想有一個以上的用戶結果(或所有用戶),更換三WHERE userid=1條件(或完全刪除它們)。

points(userid, points)sppoints(userid, spPoints)上的索引將有助於提高效率。

+0

不錯的解決方案。但是,爲什麼在子查詢中包含'WHERE userid = 1'?是出於性能的原因?爲了避免所有表聚合? – danihp 2012-07-05 14:07:38

+0

我收到了這個:'字段列表'中的未知列'points' – user995691 2012-07-05 14:08:46

+0

@danihp:爲了表現。因此,子查詢只計算特定用戶的點數。 – 2012-07-05 14:09:01