MySQL5.7默认开启only_full_group_by模式,导致GROUPBY查询报错1055。该模式要求SELECT列表必须包含所有非聚合列。可通过临时修改sql_mode,或永久修改my.cnf/my.ini配置文件,也可使用any_value()函数兼容非分组字段。建议根据实际情况选择方案。
1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'csc_risk.a.DefaultDate' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by, Time: 0.035000s
将部分数据迁移到本地测试后,发现相同的 SQL 语句可以正常执行。问题出在哪里?
长期稳定更新的攒劲资源: >>>点此立即查看<<<
先查看本地数据库版本:
SELECT VERSION()

通过查询线上数据库版本,发现同样为 5.7 版本。
5.7.24
MySQL 5.7 版本默认启用了 sql_mode = only_full_group_by 属性,正是这一属性触发了报错。明确原因后,便可着手解决。
在默认安装的 MySQL 5.7.x 版本中,only_full_group_by 模式处于开启状态。开启后,group by 的使用变得非常严格:只能返回分组字段本身,不能直接返回其他非分组字段。这意味着 group by 几乎等同于 distinct 的加强版,功能范围大幅收窄。
不过,开启该模式也有好处——MySQL 提供了 any_value(field) 函数,允许非分组字段出现在 SELECT 中,效果与关闭 only_full_group_by 相同。如果不想关闭模式,可以考虑使用该函数进行兼容。
SELECT @@sql_mode;
查询结果大致如下:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
SET @@global.sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
上述全局设置仅对新创建的数据库生效。对于已有数据库,需要在对应数据库中执行:
SET sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
注意:以上方式仅为临时解决方案,数据库重启后会失效。
Linux 系统修改 my.cnf,Windows 系统修改 my.ini。在 [mysqld] 段下添加以下配置:
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
遇到 only_full_group_by 报错时,有两个解决方向:临时关闭该模式,或修改配置文件实现永久生效。此外,使用 any_value() 函数也是一种优雅的兼容方式。希望以上排查过程能为你提供参考。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述