简体   繁体   English

MySQL SUM(列)+(SUM的子查询)

[英]MySQL SUM(column) + (SUBQUERY WITH SUM)

I want to make a query that adds up points for a team. 我想查询一个为团队加分的查询。 The points are added up by doing SUM on a column + a SUM from another table with the same team-id. 通过对列进行SUM +来自另一个具有相同team-id的表的SUM来求和。 I try to write it like this: 我尝试这样写:

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

The problem is that, when I write it in this fashion, it gives correct amount of points if the team has an entry in table "oppdrag" otherways it just returns NULL as points (poeng). 问题是,当我以这种方式编写时,如果团队在表“ oppdrag”中有一个条目,它将给出正确的分数,否则它将仅返回NULL作为分数(poeng)。

If your subquery returns NULL , this will result in trying to sum a number with NULL , which gives NULL back. 如果你的子查询返回NULL ,这将导致在试图总结了一些NULL ,这给NULL回。

To fix this, you can try using the IFNULL function, that will replace it with a 0 if the query doesn't return any values: 要解决此问题,您可以尝试使用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

I'd avoid that subquery from your select statement, it's going to kill your performance. 我会避免在您的select语句中使用该子查询,这会降低您的性能。 Also, you should really be using the correct join syntax (the style you're using is ancient). 另外,您实际上应该使用正确的联接语法(您使用的样式是古老的)。 Try something like this; 尝试这样的事情;

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

First, learn to use explicit JOIN syntax. 首先,学习使用显式的JOIN语法。 Simple rule: Never use commas in the FROM clause. 简单规则: 请勿FROM子句中使用逗号。 Always use explicit JOIN with ON . 始终使用显式JOINON

Then, you can solve your problem by including the subquery in the FROM clause: 然后,可以通过在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;

Use explicit JOIN syntax. 使用显式的JOIN语法。 Also, include all columns that aren't aggregated in GROUP BY clause. 另外,包括GROUP BY子句中未聚合的所有列。 Just because MySQL doesn't yield an error it doesn't mean that it's advisable to do it the way you did it. 仅仅因为MySQL不会产生错误,并不意味着建议按照您的方式进行操作。 Not including all columns that aren't aggregated in a group by means picking random values. 不包括通过选择随机值来将未聚集在组中的所有列。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM