我知道如果SELECT语句中有一个聚合函数,则语句中的所有其他值必须是聚合函数,或者列在GROUP BY子句中.我不明白为什么会这样.
如果我做:
SELECT Name,'Jones' AS Surname FROM People
我得到:
NAME SURNAME Dave Jones Susan Jones Amy Jones
因此,DBMS已经从每一行获取了一个值,并在结果集中附加了一个值.没关系.但如果这样做,为什么我不能做:
SELECT Name,COUNT(Name) AS Surname FROM People
看起来同样的想法,从每一行取一个值并附加一个值.但不是:
NAME SURNAME Dave 3 Susan 3 Amy 3
我得到:
You tried to execute a query that does not include the specified expression ‘ContactName’ as part of an aggregate function.
我知道这是不允许的,但是这两种情况看起来很相似,我不明白为什么.是使DBMS更容易实现吗?如果有人可以向我解释为什么它不工作,我认为应该,我会非常感激.
解决方法
聚合不能在一个完整的结果上工作,它们只能在一个组中工作.
考虑一个表,其中包含:
Person Pet -------- -------- Amy Cat Amy Dog Amy Canary Dave Dog Susan Snake Susan Spider
如果您使用对Person进行分组的查询,则会将数据分成以下组:
Amy: Amy Cat Amy Dog Amy Canary Dave: Dave Dog Susan: Susan Snake Susan Spider
如果您使用的是集合,例如计数聚合,它将为每个组生成一个结果:
Amy: Amy Cat Amy Dog Amy Canary count(*) = 3 Dave: Dave Dog count(*) = 1 Susan: Susan Snake Susan Spider count(*) = 2
所以,从Person的Person group by Person中选择Person,count(*)的查询为每个组提供了一个记录:
Amy 3 Dave 1 Susan 2
如果您尝试在结果中获取宠物字段,则不起作用,因为每个组中的该字段可能有多个值.
(有些数据库,如MysqL,确实允许这一点,只是从组内返回任何随机值,您有责任了解结果是否合理).
如果您使用聚合,但不指定任何分组,则查询仍将被分组,整个结果是单个组.因此,来自Person的查询select count(*)将创建一个包含所有记录的组,并且聚合可以对该组中的记录进行计数.结果包含每个组中的一行,由于只有一个组,结果中将会有一行.