假设我有两张桌子
CREATE TABLE users ( name VARCHAR(50) PRIMARY KEY, gender INTEGER );
CREATE TABLE likes ( username VARCHAR(50), object VARCHAR(50) );
现在,我想找出每个用户的性别和喜欢的次数
SELECT
u.name, u.gender, COUNT(*)
FROM users u
INNER JOIN likes l ON u.name = l.username
GROUP BY u.name
这里我按主键分组,这意味着每个组只有一个用户行。但是,SQL Server给出了以下错误
列'users.gender'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。
为什么抱怨?有没有办法可以达到预期的行为?
编辑:显然,必须将没有聚合函数的所有列添加到GROUP BY
子句中。我想真正的问题是:它为什么会这样?
答案 0 :(得分:2)
您描述的行为实际上与ANSI标准一致。如果一组列定义了一个唯一的行,那么其他值是"功能相关的"在那些专栏上。他们没有其他价值观。这些其他列可以包含在select
中,而不会将其包含在group by
。
识别和实施功能依赖关系的方式是通过主键和唯一键。
所以,你只想包括name
的愿望是非常合理的。 SQL Server - 以及大多数其他数据库不支持此功能(我认为该功能对于ANSI兼容性是可选的)。自9.1版以来,Postgres一直支持功能依赖。 MySQL正在修复"他们目前的group by
在5.7中支持这一点。
答案 1 :(得分:1)
索引和约束不会影响您可以编写的有效查询。这将需要可能的逻辑推断,但不需要在标准中,而不是在SQL Server中。
实际上,优化器会做所有这些推断。该计划根本不会有任何汇总。这是一个语言设计问题,他们可以理解地选择不允许这样做。它会导致脆弱的查询,并且几乎不会给客户带来任何好处。