MySQL 5.7.5+默认启用ONLY_FULL_GROUP_BY导致1055错误,需通过检查sql_mode确认;可临时设session模式绕过,或永久修改my.cnf/my.ini中[mysqld]段sql_mode删去该选项,也可改SQL适配标准(如用ANY_VALUE或补全GROUP BY)。

MySQL 5.7.5+ 默认启用 ONLY_FULL_GROUP_BY,导致 GROUP BY 查询只要 SELECT 列里有非聚合、又没出现在 GROUP BY 中的字段,就直接报错 1055 —— 这不是你 SQL 写错了,是 MySQL 在严格执行标准 SQL 规则。
查当前 sql_mode 是否含 ONLY_FULL_GROUP_BY
先确认问题是否存在,别盲目改配置:
- 执行
SELECT @@sql_mode;或SELECT @@GLOBAL.sql_mode; - 如果返回值里包含
ONLY_FULL_GROUP_BY(通常还跟着STRICT_TRANS_TABLES等),那 1055 就是它引起的 - 注意区分 session 和 global:临时改 session 不影响其他连接,但重启后失效;global 修改需权限且对新会话生效
临时绕过(开发/调试用)
适合单次排查或本地环境快速验证,不推荐上生产:
- 运行
SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', '')); - 或更稳妥地显式列出剩余项:
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; - 这个设置只对当前连接有效,断开重连就恢复原状
- 别用
SET GLOBAL sql_mode = ''清空全部模式,会关闭严格校验,可能让脏数据入库(比如插入超长字符串被静默截断)
永久关闭(Linux / Windows 配置文件修改)
这才是线上环境该走的路,但要注意操作顺序和位置:
- 找到 MySQL 配置文件:
/etc/my.cnf(Linux)或C:\ProgramData\MySQL\MySQL Server X.X\my.ini(Windows) - 在
[mysqld]段落下添加或修改sql_mode行,**必须删掉ONLY_FULL_GROUP_BY,其余项保留**,例如:sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION - 切记不要写成
sql-mode(带横线)或放在[client]段下,否则无效 - 保存后必须重启 MySQL 服务:Linux 用
sudo systemctl restart mysqld,Windows 用net stop mysql && net start mysql - 重启后再次执行
SELECT @@GLOBAL.sql_mode;确认ONLY_FULL_GROUP_BY已消失
不改配置、适配新规则的写法(最安全但要改代码)
如果你无法修改数据库配置(比如用的是云 RDS 且不开放全局变量修改权限),那就得调整 SQL 本身:
- 确保
SELECT中每个非聚合字段都出现在GROUP BY子句里,例如:SELECT name, COUNT(*) FROM sys_user GROUP BY name; - 若确实只需要一个代表值(如取分组内任意一条的
phone),可用ANY_VALUE(phone)包裹:SELECT name, ANY_VALUE(phone), COUNT(*) FROM sys_user GROUP BY name; - Laravel 等 ORM 生成的查询若报错,优先检查是否开启了
strict模式,或在 DB 配置中加'options' => [PDO::ATTR_EMULATE_PREPARES => true]有时可缓解,但根本解仍是 SQL 合规或服务端配置 - 注意:Oracle 和 PostgreSQL 也默认遵循此规则,所以这种写法其实是向标准靠拢,长期看反而减少迁移成本
真正容易被忽略的点是:很多团队只改了 session 模式以为解决了,结果上线后其他连接仍报错;或者改配置时漏掉了 [mysqld] 段落限制,导致配置根本不加载。务必以 SELECT @@GLOBAL.sql_mode 的输出为准,而不是“我以为我改好了”。











