mysql8遇到5.7之前没有的报错---Expression #1 of SELECT list is not in GROUP BY clause

103 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

问题发现的场景

  • 最近在协助网友部署项目的时候,运行项目出现以下Mysql报错: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘表名.列名’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

问题的描述

字面意思理解:

  • SELECT 列表的表达式 #1 不在 GROUP BY 子句中,并且包含非聚合列“grades.order_id”
  • 它在功能上不依赖于GROUP BY 子句中的列; 这与 sql_mode=only_full_group_by 不兼容
  • 其实是使用GROUP BY 语句违背了sql_mode=only_full_group_by。因为mysql版本5.7之后默认的模式是ONLY_FULL_GROUP_BY。

原理分析

  • 在 MySQL 5.7.5 之前,启用 ONLY_FULL_GROUP_BY 会禁用此扩展,因此需要使用非别名表达式编写 HAVING 子句。
  • 从 MySQL 5.7.5 开始,此限制被取消,因此 HAVING 子句可以引用别名,无论是否启用了 ONLY_FULL_GROUP_BY。
  • MySQL 5.7.5和以后的版本实现了对功能依赖的检测。
  • 如果启用了only_full_group_by SQL模式(在默认情况下是这样)
  • 那么MySQL就会拒绝选择列表、条件或顺序列表引用的查询
  • 这些查询将引用组中未命名的非聚合列,而不是在功能上依赖于它们。
  • 在5.7.5之前,MySQL没有检测到功能依赖项,only_full_group_by在默认情况下是不启用的。
  • 查看官方文档,发现从 MySQL 5.7.5 开始,默认 SQL 模式包括 ONLY_FULL_GROUP_BY
  • 在 5.7.5 之前,MySQL 不检测函数依赖,并且默认不启用 ONLY_FULL_GROUP_BY。这可能会导致一些sql语句失效。

问题解决

  • 执行以下sql命令,可以查看 sql_mode 的内容。
  • 最后能发现原来是mysql 8.0 以上取消了NO_AUTO_CREATE_USER这个关键字,在mysql中的sql_mode中删掉这个关键字即可。
SELECT @@sql_mode;

SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
FLUSH PRIVILEGES;

在这里插入图片描述

  • 实测可行,修改成功!