简体   繁体   English

SQL Server:SUM多列而不使用分组依据

[英]SQL Server : SUM Multiple columns without using group by

I have table like this. 我有这样的桌子。

Table 1 : 表格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

Table 2 : 表2:

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

Query: 查询:

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 

I want it return like this 我希望它这样返回

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

But it returns 但它返回

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

How to fix it? 如何解决?

[EDIT] i made a mistake on calculate score. [编辑]我在计算分数上犯了一个错误。

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

score is SUM of each row contains s1+s2+s3 分数是每一行的总和,包含s1 + s2 + s3

Use SUM : 使用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 

Also, it is preferable to use explicit join syntax, as in the above query. 另外,最好使用显式联接语法,如上面的查询中所示。

Use SUM function 使用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 

First of all you are using an antiquated join syntax that you shouldn't use anymore. 首先,您正在使用过时的连接语法,该语法不再应使用。 Use explicit joins instead: 改用显式联接:

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

Then you join with t_sub, but you select no field from it, so why join at all? 然后,您使用t_sub加入,但没有选择任何字段,那么为什么要加入? Your query could be re-written as: 您的查询可以改写为:

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

Then you group by name, but you don't say what aggregate on s1 etc. you want to see. 然后按名称分组,但是您没有说想查看s1等上的聚合。 Do you want to sum the maximum s1, s2, s3? 您是否要求和最大s1,s2,s3? Or the minimum values? 或最小值? Or the avarages? 还是平均水平? Probably the sums. 大概是和。 Hence: 因此:

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

or simply 或简单地

SUM(s1 + s2 + s3)

But then: can s1, s2 or s3 be NULL? 但是然后:s1,s2或s3可以为NULL吗? Then you'd have to deal with that, too: 然后,您也必须处理该问题:

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

Here is the final query: 这是最终查询:

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;

Or is the name in t_score unique (over all records or at least per id_sub)? 还是t_score中的名称是唯一的(在所有记录中,或者至少在每个id_sub中)? Then you wouldn't have to aggregate records at all (ie no SUM , no GROUP BY ): 然后,您将根本不需要汇总记录(即,没有SUM ,没有GROUP BY ):

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

You can get what you need without GROUP BY and SUM, if you don't have duplicates with same id and name: 如果没有相同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

Output: 输出:

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

(3 row(s) affected)

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

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