本文最后更新于 2024-07-07,文章内容可能已经过时。

MySQL5.7版本sql_mode=only_full_group_by问题解决办法

报错信息:

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘city.name.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.5及以上功能依赖检测功能。如果启用了ONLY_FULL_GROUP_BY

对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中。简而言之,就是SELECT后面接的列必须被GROUP BY后面接的列所包含。如:
select A,B from table group by A,B,C; (正确)
select A,B,C from table group by A,B; (错误)

解决方法:

查看sql_mode

mysql> select @@sql_mode;
+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@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 |
+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

去掉ONLY_FULL_GROUP_BY,重新设置值。【下次重启数据库后失效】

mysql> 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';
mysql>exit
#退出后,再次登录查看

mysql> select @@sql_mode;
+------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode                                                                                                             |
+------------------------------------------------------------------------------------------------------------------------+
| STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

上面这种方式数据库重启后设置会失效,只是修改了内存中的值,不能永久改变。想要永久解决需要在配置文件中修改

永久修改方式,修改/etc/my.cnf 配置文件

vim /etc/my.cnf
[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
.......

修改完后,重启数据库即可

systemctl restart mysqld