MySQL:GROUP BY上的非聚合字段会发生什么?

时间:2015-07-29 10:11:36

标签: mysql aggregate-functions

我对MySQL中的以下行为有一个基本的问题。

假设我们执行以下GROUP BY

SELECT a, b, SUM(c)
FROM table
GROUP BY b;

字段a会发生什么变化,既不会汇总也不会包含在GROUP BY字段中?

MySQL是否只是隐含地将FIRST(a)应用于a?如果是这样,这种行为是否一致,或者是否从a的所有值中获取随机值?

2 个答案:

答案 0 :(得分:3)

MySQL> 5.7.5

这是非法查询。

您将收到如下错误:

ERROR 1055 (42000): Expression #1 of SELECT list is not in 
GROUP BY clause and contains nonaggregated column 'a' 
which is not functionally dependent on columns in 
GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
  

MySQL 5.7.5及更高版本实现了对功能依赖的检测。如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下是这样),则MySQL拒绝查询,其中选择列表,HAVING条件或ORDER BY列表引用既未在其中命名的非聚合列GROUP BY子句在功能上也不依赖于它们

https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

的更多详情

MySQL< 5.7.5

Short anwser:它是一个有效的查询,但服务器可以自由返回任何值

阅读此https://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html节目:

  

12.16.3 GROUP BY的MySQL处理   在标准SQL中,包含GROUP BY子句的查询无法引用   选择列表中未在GROUP中命名的非聚合列   BY子句。例如,此查询在标准SQL中是非法的,因为   选择列表中的名称列不会出现在GROUP BY:

SELECT o.custid, c.name, MAX(o.payment)
FROM orders AS o, customers AS c
WHERE o.custid = c.custid
GROUP BY o.custid;
     

要使查询合法,必须从选择列表中省略name列,或在GROUP BY子句中命名。

     

MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。这意味着前面的查询在MySQL中是合法的。您可以通过避免不必要的列排序和分组来使用此功能来获得更好的性能。但是,当GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时,这非常有用。 服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。此外,添加ORDER BY子句不会影响每个组中值的选择。选择值后会对结果集进行排序,而ORDER BY不会影响服务器选择的每个组中的值。

因此无法确定该值将是什么(如果该组有更多值)

答案 1 :(得分:1)

这是查询处理器从存储介质返回的第一个结果值,具体取决于所选的查询策略。从技术上讲,这是未定义的,但是你的表没有任何其他指标,这是合理的确定性,但你受到优化者的支配。

依靠你的危险。这就是发明窗口功能的原因。