SQL Server:SUM多列而不使用group by

时间:2016-05-10 09:49:51

标签: sql sql-server group-by

我有这样的表格。

表1:

ID Name s1 s2 s3 id_sub
-----------------------
1  John 90 80 90 1
2  Nick 80 70 90 1
3  Mike 95 95 80 1
4  John 70 70 70 2

表2:

id_sub sub sub_name
---------------
1      ph  physic
2      mt  math
3      cm  chemistry

查询:

SELECT t_score.name, (t_score.s1 + t_score.s2 + t_score.s3) as score 
FROM t_score, t_sub
where t_score.id_sub = t_sub.id_sub AND t_score.id_sub = 1
GROUP BY name 

我希望它像这样返回

Name score
----------
John 260
Nick 240
Mike 210

但它返回

Column 't_score.s1' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
Column 't_score.s2' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
Column 't_score.s3' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

如何解决?

[编辑] 我在计算分数上犯了一个错误。

Name score
----------
John 260
Nick 240
Mike 270

得分是每行的SUM包含s1 + s2 + s3

4 个答案:

答案 0 :(得分:4)

使用SUM

SELECT t_score.name, SUM(t_score.s1 + t_score.s2 + t_score.s3) as score 
FROM t_score
INNER JOIN t_sub ON t_score.id_sub = t_sub.id_sub
WHERE t_score.id_sub = 1
GROUP BY name 

此外,最好使用显式连接语法,如上面的查询。

答案 1 :(得分:3)

使用SUM函数

SELECT t_score.name, SUM(t_score.s1 + t_score.s2 + t_score.s3) as score 
FROM t_score, t_sub
where t_score.id_sub = t_sub.id_sub AND t_score.id_sub = 1
GROUP BY name 

答案 2 :(得分:1)

首先,您使用的是过时的连接语法,不应再使用了。请改用显式联接:

FROM t_score
JOIN t_sub ON t_sub.id_sub = t_score.id_sub

然后你加入了t_sub,但你没有从中选择任何一个字段,那么为什么要加入呢?您的查询可以重写为:

SELECT name, (s1 + s2 + s3) AS score 
FROM t_score
WHERE id_sub = 1
GROUP BY name;

然后按名称分组,但是你没有说出你想看到的s1等上的聚合。你想总和最大s1,s2,s3吗?还是最小值?还是avarages?可能是总和。因此:

SUM(s1) + SUM(s2) + SUM(s3)

或只是

SUM(s1 + s2 + s3)

但是:s1,s2或s3可以为NULL吗?那么你也必须处理它:

COALESCE(SUM(s1), 0) + COALESCE(SUM(s2), 0) + COALESCE(SUM(s3), 0)

以下是最终查询:

SELECT 
  name, 
  COALESCE(SUM(s1), 0) + COALESCE(SUM(s2), 0) + COALESCE(SUM(s3), 0) AS score 
FROM t_score
WHERE id_sub = 1
GROUP BY name;

或者t_score中的名称是唯一的(在所有记录上或至少每个id_sub)?那么你根本不必聚合记录(即没有SUM,没有GROUP BY):

SELECT 
  name, 
  COALESCE(s1, 0) + COALESCE(s2, 0) + COALESCE(s3, 0) AS score 
FROM t_score
WHERE id_sub = 1;

答案 3 :(得分:1)

如果您没有具有相同ID和名称的重复项,您可以在没有GROUP BY和SUM的情况下获得所需内容:

;WITH cte AS (
SELECT *
FROM (VALUES
(1, 'John', 90, 80, 90, 1),
(2, 'Nick', 80, 70, 90, 1),
(3, 'Mike', 95, 95, 80, 1),
(4, 'John', 70, 70, 70, 2)
) as t (ID, Name, s1, s2, s3, id_sub)
)

SELECT  name,
        IsNull(s1,0)+IsNull(s2,0)+IsNull(s3,0) as [score]
FROM cte
WHERE id_sub = 1

输出:

name score
---- -----------
John 260
Nick 240
Mike 270

(3 row(s) affected)