2016-08-23 118 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