Mysql 8.0 only_full_group_by 问题

249 阅读2分钟

为什么Mysql 8.0 only_full_group_by 默认自动开启?

MySQL官网对于 8.0 开启 ONLY_FULL_GROUP_BY的解释

SQL-92 and earlier does not permit queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are not named in the GROUP BY clause. For example,this query is illegal in standard SQL-92 because the nonaggregated name column in the select list does not appear in the GROUP BY:

大概意思是说,SQL-92标准要求SELECT、HAVING、ORDER BY中出现的字段名必须包含在GROUP BY当中。所以需要符合SQL-92标准。

为什么查询字段需要包含在Group By当中?

举个例子   

婚姻状况人数
已婚    102
未婚    98

假设要统计已婚未婚人数,你的sql应该是: select is_marry ,count(*) from user group by is_marry

但是 如果加上一列性别,在已婚和未婚里面 男女都有 ,这时候你的sql还要查出sex,但是sql是不知道这已婚102人应该是写男的还是写女的 ,因为男女都有。这个时候即使显示出来 sex 字段,那么也不具备实际的意义。我们不能说 男/女 已婚人数为 102。 

婚姻状况人数性别
已婚    102--
未婚    98--

所以正确的应该是再加上一个分组条件,也就是为什么分组的时候select的字段为什么一定要出现在group by 字段中。

婚姻状况人数性别
已婚    102
已婚    92
未婚    98
未婚    108

你的sql应该是 select is_marry , count(*) , sex from user group by is_marry , sex ;

如何解决 Group by 问题?

问题的本质是因为 查询的字段 不包含在 group by 字段中,92标准认为这种情况下查询的非 group by 字段是没有实际意义的。

因此。解决方案有以下几种。

一、 调整优化SQL。确认查询非 group by 字段是否有必要。

如果有必要,建议使用  any_value( field ) 方式(对于 field 字段选择哪个值都无所谓情况)

二、可以选择取消 only_full_group_by

only_full_group_by 不仅仅是针对 group by 语句,也针对所有的聚合函数,比如:SUM、AVG、MAX、MIN。示例:SELECT a, SUM(b) FROM mytable  字段 a 取什么值也无法确定。

最后,如果 group by 字段为 主键,或者唯一索引,此时也不会有任何问题。因为,group by 唯一索引没有意义,与普通查询没有区别。