列的原因在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中

dav*_*ine 248 sql group-by aggregate-functions

可能重复:
SQL中的GROUP BY /聚合函数混淆

我收到了一个错误 -

列'Employee.EmpID'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中.


select loc.LocationID, emp.EmpID
from Employee as emp full join Location as loc 
on emp.LocationID = loc.LocationID
group by loc.LocationID 
Run Code Online (Sandbox Code Playgroud)

这种情况符合Bill Karwin给出的答案.

修正以上,适合ExactaBox的答案 -

select loc.LocationID, count(emp.EmpID) -- not count(*), don't want to count nulls
from Employee as emp full join Location as loc 
on emp.LocationID = loc.LocationID
group by loc.LocationID 
Run Code Online (Sandbox Code Playgroud)

原始问题 -

对于SQL查询 -

select *
from Employee as emp full join Location as loc 
on emp.LocationID = loc.LocationID
group by (loc.LocationID)
Run Code Online (Sandbox Code Playgroud)

我不明白为什么我会收到这个错误.我想要做的就是加入表格,然后将特定位置的所有员工分组在一起.

我想我对自己的问题有部分解释.告诉我它是否正常 -

要对在同一位置工作的所有员工进行分组,我们必须首先提及LocationID.

然后,我们不能/不提及它旁边的每个员工ID.相反,我们提到该位置的员工总数,即我们应该SUM()在该位置工作的员工.为什么我们这样做呢,我不确定.因此,这解释了"它不包含在聚合函数中"部分错误.

GROUP BY错误的子句部分有什么解释?

Bil*_*win 511

假设我有下表T:

a   b
--------
1   abc
1   def
1   ghi
2   jkl
2   mno
2   pqr
Run Code Online (Sandbox Code Playgroud)

我做以下查询:

SELECT a, b
FROM T
GROUP BY a
Run Code Online (Sandbox Code Playgroud)

输出应该有两行,一行在哪里a=1,第二行在哪里a=2.

但是这两行中每一行的b值应该是什么?每种情况都有三种可能性,查询中没有任何内容可以清楚地说明每个组中为b选择哪个值.这是模棱两可的.

这演示了单值规则,它禁止在运行GROUP BY查询时获得的未定义结果,并且您在select-list中包含既不属于分组条件的任何列,也不会出现在聚合函数中(SUM, MIN,MAX等).

修复它可能如下所示:

SELECT a, MAX(b) AS x
FROM T
GROUP BY a
Run Code Online (Sandbox Code Playgroud)

现在很清楚你想要以下结果:

a   x
--------
1   ghi
2   pqr
Run Code Online (Sandbox Code Playgroud)

  • 当人们花时间解释使用第一原则时,请喜欢它.比尔.谢谢. (31认同)
  • @davidblaine,MySQL有一个函数GROUP_CONCAT().http://dev.mysql.com/doc/refman/5.5/en/group-by-functions.html#function_group-concat但在标准SQL中,每列只应包含一个值.这也是关系理论的基础. (17认同)
  • 比尔 - 一旁 - 你说它并不"清楚每组中选择b的价值".为什么SQL不将b1,b2,b3全部放在该列中? (4认同)
  • 我认为这是MSSQL的缺点,因为当我们有一些LEFT JOIN并按正确表的PK分组时,那么我们就必须能够轻松地获得正确表的列,而不会出现任何歧义(MySQL处理此情况)。 (2认同)
  • 在SQL Server 2017中可以使用String_Agg来解决上述问题 (2认同)
  • @Postlagerkarte,很高兴听到他们最终创建了一个聚合函数来完成这项常见任务。使用 FOR XML PATH 似乎总是一个丑陋的技巧。 (2认同)

Joh*_*Woo 62

MYSQL如果设置为禁用ONLY_FULL_GROUP_BY服务器模式(默认情况下),则查询将起作用.但在这种情况下,您使用的是不同的RDBMS.因此,为了使您的查询有效,请将所有非聚合列添加到您的GROUP BY子句中,例如

SELECT col1, col2, SUM(col3) totalSUM
FROM tableName
GROUP BY col1, col2
Run Code Online (Sandbox Code Playgroud)

非聚集的列是指该列未被传递到像聚合函数SUM,MAX,COUNT等.

  • 这就像具有多个内部连接的魅力一样。 (2认同)

Exa*_*Box 16

"我想要做的就是加入表格,然后将特定地点的所有员工分组在一起."

听起来你想要的是SQL语句的输出列出公司的每个员工,但首先是阿纳海姆办事处的所有人,然后是布法罗办事处的人,然后是克利夫兰办事处的人(A, B,C,得到它,显然我不知道你有什么位置).

在这种情况下,丢失GROUP BY语句.所有你需要的是 ORDER BY loc.LocationID

  • 然后将原始示例的第一行替换为:SELECT loc.LocationID,COUNT(*) (7认同)
  • 那不是我要表达的意思.order by将所有员工一个接一个地放在同一个城市.它将为所有城市做到这一点.我需要知道*一个城市有多少*员工,而不是*一个城市的哪些员工*.说得通 ? (3认同)
  • 是的,那就是我想要的.谢谢.看起来我没有正确构建我的问题.但是,Bill Karwin的回答让我理解了错误背后的原因.所以我接受了他的.再次感谢. (3认同)

Ale*_*x W 10

基本上,这个错误说的是,如果你要使用该GROUP BY子句,那么你的结果将是一个关系/表,每个组都有一行,所以在你的SELECT语句中你只能"选择"你的列正在对该列进行分组并使用聚合函数,因为其他列不会出现在结果表中.