MySQL this is incompatible with sql_mode=only_full_group_by错误

问题背景:

闯关答题,需要获取用户所有关卡的答题情况,并统计通过的次数分数等

image.png)image.png

一、原理层面

这个错误发生在 mysql 5.7 版本及以上版本会出现的问题:
mysql 5.7 版本默认的 sql 配置是:sql_mode=”ONLY_FULL_GROUP_BY”,这个配置严格执行了”SQL92 标准”。
很多从 5.6 升级到 5.7 时,为了语法兼容,大部分都会选择调整 sql_mode,使其保持跟 5.6 一致,为了尽量兼容程序。

二、sql 层面

在 sql 执行时,出现该原因:
简单来说就是:输出的结果是叫 target list,就是 select 后面跟着的字段,还有一个地方 group by column,就是
group by 后面跟着的字段。由于开启了 ONLY_FULL_GROUP_BY 的设置,所以如果一个字段没有在 target list
和 group by 字段中同时出现,或者是聚合函数的值的话,那么这条 sql 查询是被 mysql 认为非法的,会报错误。

1、查看 sql_mode 的语句如下

1
select @@GLOBAL.sql_mode;

1、解决方案一 (推荐解决方案二)

① 解决方案一:sql 语句暂时性修改 sql_mode

1
set global sql_mode='STRICT_RANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

重启 mysql 数据库服务之后,ONLY_FULL_GROUP_BY 还会出现。
② 解决方案二:完美解决方案。

需修改 mysql 配置文件,通过手动添加 sql_mode 的方式强制指定不需要 ONLY_FULL_GROUP_BY 属性,
my.cnf 位于 etc 文件夹下,vim 下光标移到最后,添加如下:

1
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

重启 mysql 就好。

安装配置 mysql 的时候可能会遇到需要配置 my.cnf 配置文件的情况,但是不管是用 homebrew 还是用 mysql 安装包安装的客户端都不会生成这个文件(官方解释)。

  1. 如果你只是想确认 mysql 加载的是哪个配置文件那你可以使用以下方法进行确认。
1
mysql --verbose --help | grep my.cnf

会得到类似以下的几个地址,默认是在/etc/下的 my.cnf。

  1. 如果你没有使用过 my.cnf,那就必须手动创建一个 my.cnf 目录放在上一条我们看到的几个目录下面,通常/usr/local/mysql/support-files/my-default.cnf 目录下会有一个默认文件,你把它拷贝到指定位置做自定义修改就 ok 了。

附阿里云 rds 增加 ONLY_FULL_GROUP_BY 属性的方法:

  1. 通过相关配置查看 sql_mode 内包含的 SQL 模式,如下所示,确认未设置 ONLY_FULL_GROUP_BY 语法支持。
1
sql_mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_UNSIGNED_SUBTRACTION,NO_DIR_ IN_CREATE,POSTGRESQL,ORACLE,MSSQL,DB2,MAXDB,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,MYSQL 323,MYSQL40,ANSI,NO_AUTO_VALUE_ON_ZERO,NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLES,STRICT_ALL_TABLES, NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,HIGH_NOT _PRECEDENCE,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH
  1. 执行 select @@global.sql_mode SQL 语句,确认仍然包含 ONLY_FULL_GROUP_BY 参数。
  2. 上述 sql_mode 中包含了 ANSI 参数,而 ONLY_FULL_GROUP_BY 为 ANSI 的子集,所以 sql_mode 会自动设置为 ONLY_FULL_GROUP_BY。

扫一扫,分享到微信

微信分享二维码

请我喝杯咖啡吧~

支付宝
微信