MySQL 报错 this is incompatible with sql_mode=only_full_group_by

MySQL 报错 this is incompatible with sql_mode=only_full_group_by

问题描述

前段时间服务器出现问题,运维人员解决相关问题后,重新启动服务,结果系统出现异常

1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'ecopc.problem_demo.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

报错原因

学习MySQL的时候我们知道

在使用 GROUP BY 时,SELECT 列表中只能包含聚合函数或 GROUP BY 子句中指定的列

定位到系统中报错SQL时候,发现确实 SELECT 后面跟的字段中存在不满足前面条件的字段,所以报错了。网上一查,跟 MySQL配置 sql_mode 有关。MySQL在5.7版本之后,sql_mode 默认包含 ONLY_FULL_GROUP_BYONLY_FULL_GROUP_BY 作用也就是保证我们前面说的 GROUP_BY 使用注意事项

解决办法

查看MySQL版本

SELECT VERSION();

我这里是 5.7.32,查看 sql_mode

SELECT @@GLOBAL.sql_mode; //查看mysql全局设置
SELECT @@SESSION.sql_mode; //查看当前数据库设置

image-dsmi.png

可以看到确实包含 ONLY_FULL_GROUP_BY

方法一

使用ANY_VALUE()函数:MySQL提供了 ANY_VALUE()函数作为对 ONLY_FULL_GROUP_BY模式的一种补充。这个函数可以允许在SELECT列表中引用非GROUP BY列

方法二

修改 sql_mode,去掉 ONLY_FULL_GROUP_BY

# 注意哈,我这里设置值是根据查询出来的sql值去掉`ONLY_FULL_GROUP_BY`设置的,不同版本sql_mode可能不一样
# 所以根据自己数据库去设置,不要直接cv,设置全局还是当前数据库根据需要来
SET  @@SESSION.sql_mode = 'STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

这种方式存在的问题是修改是临时生效的,当我们数据库重启时,仍旧会默认开启 ONLY_FULL_GROUP_BY想要永久生效,就得修改配置文件了

方法三

修改配置文件,MySQL的配置文件通常位于 /etc/mysql/my.cnf,但也可能位于 /etc/mysql/mysql.conf.d/mysqld.cnf 或其他位置,编辑配置文件,修改 sql_mode值,去掉 ONLY_FULL_GROUP_BY就行了

[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"