我可以在SQL中的聚合函数中包含非聚合列而不将其放入GROUP BY子句中吗?

时间:2011-01-27 20:57:14

标签: sql sql-server tsql group-by aggregate

采取以下表格......

Classes
ClassId ClassName
1       Math
2       Math
3       Science
4       Music

Registrations
RegistrationId ClassId StudentName
1              1       Stu
2              1       Rick
3              2       John
4              4       Barb
5              4       Dan
6              3       Einstein

是的,有两个同名(Math)的课程可能在不同的时间。我想获得一个班级列表和每个学生注册的学生人数。我想要以下列(ClassId,ClassName,StudentCount)。

我对此的尝试将是......

SELECT Classes.ClassId, Classes.ClassName, Count(Registrations.RegistrationId)
FROM Classes
INNER JOIN Registrations ON Classes.ClassId = Registrations.ClassId
GROUP BY Classes.ClassId

(注意我想GroupBy ClassId但不是ClassName)。这在SQLServer 2008中是否可行?显然我问,因为SQL抱怨

"ClassName is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

谢谢!

4 个答案:

答案 0 :(得分:11)

不,SQL Server不允许您省略GROUP BY中未包含在聚合函数中的列。包含类名称没有坏处,因为group by将按列组合执行:

  SELECT c.classid, 
         c.classname, 
         COUNT(r.registrationid)
    FROM CLASSES c
    JOIN REGISTRATIONS r ON r.classid = c.classid
GROUP BY c.classid, c.classname

您可以使用以下方法根据计数得出一个表:

  SELECT c.classid, 
         c.classname, 
         r.num
    FROM CLASSES c
    JOIN (SELECT t.classid,
                 COUNT(*) AS num
            FROM REGISTRATIONS t
        GROUP BY t.classid) r ON r.classid = c.classid

答案 1 :(得分:5)

在GROUP BY语句中包含Classes.ClassName应该没有任何害处。您将通过不同的ClassId和ClassName对进行分组,因此(1,'Math')和(2,'Math')仍然是两个不同的分组。

答案 2 :(得分:2)

您可以将ClassName放在group by子句中,这样就可以了,因为它是ClassID的1到1:

SELECT Classes.ClassId,Classes.ClassName,Count(Registrations.RegistrationId) FROM Classes INNER JOIN在Classes.ClassId = Registrations.ClassId上注册 GROUP BY Classes.ClassId,Classes.ClassName

或在select子句中放入MAX(ClassName)。任何一个都会产生相同的结果。

答案 3 :(得分:1)

不,你不能:这是一个矛盾。

GROUP BY =折叠为离散值。如果你没有崩溃,你需要聚合它。

碰巧,你会得到相同的结果,因为ClassName依赖于ClassID。