文章目录
- 报错信息
- DataGrip 报错还原
- Navicat 报错还原
- 报错原因
- 解决方案
- 查看当前 sql mode
- 方案一:临时解决
- 方案二:永久解决
- 方案三:使用 any_value() 或 group_concat()
- 方案四:调整实现思路,避开 GROUP BY 使用
我是一名立志把细节说清楚的博主,欢迎【关注】🎉 ~
原创不易, 如果有帮助 ,记得【点赞】【收藏】 哦~ ❥(^_-)~
如有错误、疑惑,欢迎【评论】指正探讨,我会尽可能第一时间回复的,谢谢支持
报错信息
DataGrip 报错还原
[42000][1055] Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘xx库.xx表.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
Navicat 报错还原
1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘school.student_100w.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
报错原因
MySQL 5.7后,MySQL的 SQL_MODE
配置项会默认包含 only_full_group_by
模式,这个配置会严格执行SQL92标准。如果代码中含有group by聚合操作,那么select中的列,除了使用聚合函数之外的,如max()、min()等,都必须出现在group by中。
要求:从学生表中,根据班级编号,分组查询班级编号、班级名称。
报错:SELECT 查询的字段和 GROUP BY 分组依据的字段不统一。
# SELECT 查询的字段和 GROUP BY 分组依据的字段不统一,会报错。
SELECT class_number, class_name FROM student GROUP BY class_number;
调整:将SELECT 查询的字段和 GROUP BY 分组依据的字段统一。
# SELECT 查询字段和 GROUP BY 分组依据的字段统一后就不会报错。
SELECT class_number, class_name FROM student GROUP BY class_number, class_name ;
# SELECT 查询字段和 GROUP BY 分组依据的字段统一后就不会报错。
SELECT class_number FROM student GROUP BY class_number;
解决方案
查看当前 sql mode
执行 SQL
语句,查看当前的 sql_mode
。
SELECT @@global.sql_mode;
注意默认的列宽可能无法直接查看全部内容,容易造成误解,需要手动拉伸列宽查看。
拉伸列宽后可查看全部内容,(不同版本的 MySQL
默认值可能不同)。
方案一:临时解决
排除当前 sql_mode
中 ONLY_FULL_GROUP_BY
值,复制剩下的值。执行设置语句:
SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
但是如果当前数据库重启后,还是回归默认设置,即包含 ONLY_FULL_GROUP_BY
模式。
方案二:永久解决
- windows系统,直接修改
my.ini
配置文件。
在 [mysqld]
模块下新增一行配置:
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
注意:
- 不能有多余的符号,我之前在结尾加了分号导致重启失败。
- 点击保存文件,不要直接关掉。 不然设置丢失,是不会生效的。
Linux系统,思路是一样的,都是找配置文件修改配置。但是不同Mysql版本,路径和配置文件名称可能不同:大致可能是 /etc/my.cnf
或者 /mysql.conf
之类的名称。
数据库重启后生效。
方案三:使用 any_value() 或 group_concat()
- any_value():
- 将分到同一组的数据里第一条数据的指定列值作为返回数据。 (any_value()函数就是MySQL提供的用来抑制ONLY_FULL_GROUP_BY值被拒绝的)
SELECT class_number, any_value(class_name) FROM student GROUP BY class_number;
实际使用效果如下:
- group_concat():
- 将分到同一组的数据默认用逗号隔开作为返回数据。
SELECT class_number, group_concat(class_name) FROM student GROUP BY class_number;
实际使用效果如下:
方案四:调整实现思路,避开 GROUP BY 使用
通过对SQL的查询思路调整,代码逻辑调整等,部分场景是可以绕开对 GROUP BY 关键字筛选依赖的。这个需要结合实际业务场景,自己去思考调整了。
我是一名立志把细节说清楚的博主,欢迎【关注】🎉 ~
原创不易, 如果有帮助 ,记得【点赞】【收藏】 哦~ ❥(^_-)~
如有错误、疑惑 ,欢迎【评论】指正探讨,我会尽可能第一时间回复的,谢谢支持