2016-08-23 196 views
1

我想爲查詢添加一個團隊的積分。通過在列上執行SUM +來自具有相同team-id的另一個表中的SUM來累計點數。我嘗試寫這樣的:MySQL SUM(column)+(SUBQUERY WITH SUM)

SELECT 
    k.id, 
    s.fylke, 
    s.Kommune, 
    s.Skolenavn, 
    k.schoolid, 
    k.number, 
    k.letter, 
    SUM(e.amount) + (SELECT SUM(poeng) FROM oppdrag WHERE klasseid=k.id) AS poeng 
FROM skoler AS s, klasser AS k, etappe AS e 
WHERE s.id=k.schoolid AND k.id=e.klasseid AND e.year='2016' 
GROUP BY k.id 
ORDER BY poeng 

的問題是,當我把它寫在這種方式,它給分的正確數量如果球隊在表「oppdrag」 otherways條目它只返回NULL作爲點(poeng)。

回答

2

如果您的子查詢返回NULL,則會導致嘗試將NULLNULL相加,從而返回NULL

爲了解決這個問題,你可以嘗試使用IFNULL功能,也將與0替換如果查詢不返回任何值:

SELECT 
    k.id, 
    s.fylke, 
    s.Kommune, 
    s.Skolenavn, 
    k.schoolid, 
    k.number, 
    k.letter, 
    SUM(e.amount) + IFNULL((SELECT SUM(poeng) FROM oppdrag WHERE klasseid=k.id), 0) AS poeng 
FROM skoler AS s, klasser AS k, etappe AS e 
WHERE s.id=k.schoolid AND k.id=e.klasseid AND e.year='2016' 
GROUP BY k.id 
ORDER BY poeng 
+0

謝謝,以簡單的方式解決問題:) – johnohod

1

首先,要學會使用顯式JOIN語法。簡單的規則:從不FROM子句中使用逗號。 總是使用明確的JOINON

然後,您可以通過包括FROM子句中的子查詢解決您的問題:

SELECT ske.*, ske.amount + COALESCE(od.amount, 0) as poenb 
FROM (SELECT k.id, s.fylke, s.Kommune, s.Skolenavn, k.schoolid, 
      k.number, k.letter, SUM(e.amount) as amount 
     FROM skoler s JOIN 
      klasser k 
      ON s.id = k.schoolid JOIN 
      etappe e 
      ON k.id = e.klasseid AND e.year = '2016' 
     GROUP BY k.id 
    ) ske LEFT JOIN 
    (SELECT od.klasseid, SUM(od.poeng) as amount 
     FROM oppdrag od 
     GROUP BY od.klasseid 
    ) od 
    ON od.klasseid = k.id 
ORDER BY poeng; 
2

我會避免從你的SELECT語句子查詢,它會殺了你的表現。此外,你應該真正使用正確的連接語法(你使用的風格是古老的)。嘗試這樣的事情;

SELECT 
    k.id, 
    s.fylke, 
    s.Kommune, 
    s.Skolenavn, 
    k.schoolid, 
    k.number, 
    k.letter, 
    SUM(e.amount) + ISNULL(SUM(od.poeng),0) AS poeng 
FROM skoler AS s 
INNER JOIN klasser AS k 
    ON s.id = k.schoolid 
INNER JOIN etappe AS e 
    ON k.id = e.klasseid 
LEFT JOIN oppdrag od 
    ON od.klasseid = k.id 
WHERE e.year='2016' 
GROUP BY k.id 
ORDER BY poeng 
+0

你可能是正確的。用正確的JOINS寫入看起來會更好。但它看起來像兩種查詢方式使用相同的時間來運行,所以我不確定它會殺死性能。 – johnohod

+0

這將取決於您要處理的數據量。具有select的子查詢將針對結果集的每一行調用一次。如果你加入,那麼它將被稱爲總共一次。 –

+0

我有一種感覺,子查詢不會每行運行一次。我已經多次使用這樣的子查詢,並且性能很好。我認爲查詢在執行之前已經過優化。但我同意,你的語法更好,並且對發生的事情有更多的控制,我的是sl :)不馴的:) – johnohod

1

使用明確的JOIN語法。此外,包括GROUP BY子句中未彙總的所有列。僅僅因爲MySQL不會產生錯誤,並不意味着按照你所做的方式來執行它是明智的。不包括通過挑選隨機值的方式在一個組中未彙總的所有列。

SELECT 
    k.id, 
    s.fylke, 
    s.Kommune, 
    s.Skolenavn, 
    k.schoolid, 
    k.number, 
    k.letter, 
    COALESCE(SUM(e.amount), 0) + COALESCE(SUM(o.poeng), 0) AS poeng 
FROM skoles AS s 
INNER JOIN klasser AS k ON s.id = k.schoolid 
INNER JOIN etappe AS e ON k.id = e.klasseid 
LEFT JOIN (SELECT klasseid, SUM(poeng) AS poeng FROM oppdrag) AS o ON o.klasseid = k.id 
WHERE e.year = '2016' 
GROUP BY k.id, s.fylke, s.Kommune, s.Skolenavn, k.schoolid, k.number, k.letter 
ORDER BY poeng