这不是 phpMyAdmin 的问题,而是 MySQL 5.7+ 默认启用 ONLY_FULL_GROUP_BY 模式所致;该模式要求 SELECT 中非聚合字段必须出现在 GROUP BY 子句或被聚合函数包裹,否则报错 1055;临时方案为执行 SET SESSION sql_mode=...,永久方案需修改 my.ini/my.cnf 并重启服务;更推荐重写 SQL 以符合语义逻辑。
直接结论:这不是 phpmyadmin 的问题,而是它背后 mysql(5.7+)默认启用了 only_full_group_by 模式,强制要求 select 中每个非聚合字段必须出现在 group by 里,或被聚合函数包裹。
为什么在 phpMyAdmin 里一执行 GROUP BY 就报错 1055?
你写的语句类似这样:
SELECT id, name, COUNT(*) FROM user GROUP BY status;
MySQL 直接拒绝——因为 id 和 name 既没在 GROUP BY status 中,也没用 MAX()、GROUP_CONCAT() 等包裹。报错信息里那串 this is incompatible with sql_mode=only_full_group_by 就是根源。
- 该限制从 MySQL 5.7.5 起默认开启,phpEnv 自带的 MySQL 多为 5.7 或 8.x,所以必现
- phpMyAdmin 只是客户端,它不控制 SQL 模式,所有校验由 MySQL 服务端执行
- 即使你在 phpMyAdmin 的 SQL 窗口里手动改了
sql_mode,关掉标签页就失效
临时绕过:只对当前 phpMyAdmin 连接生效
在 phpMyAdmin 的「SQL」标签页中,先执行这条语句,再运行你的 GROUP BY 查询:
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
- 必须用
SESSION(不是GLOBAL),否则需要 root 权限且影响所有连接 - 不能写
REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')—— 容易误删其他模式项(比如把STRICT_TRANS_TABLES里的TABLES干掉) - 如果你用 PHP 连接数据库(如 PDO),得在每次
new PDO()后立刻执行一次这个SET,否则照样报错
永久关闭 ONLY_FULL_GROUP_BY(phpEnv 用户专用路径)
编辑 phpEnv 自带 MySQL 的配置文件:
立即学习“PHP免费学习笔记(深入)”;
- Windows:
phpenv\mysql\my.ini - Linux/macOS:
phpenv/mysql/my.cnf
在 [mysqld] 段落下添加(注意是完整覆盖,不是追加):
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
- 必须显式列出全部模式项,漏掉
STRICT_TRANS_TABLES会导致 MySQL 自动补回默认值(含ONLY_FULL_GROUP_BY) - 改完后必须重启 phpEnv 的 MySQL 服务(通过控制面板点「重启 MySQL」,或命令行运行
phpenv restart mysql) - 验证是否生效:在 phpMyAdmin 执行
SELECT @@GLOBAL.sql_mode;,确认输出里没有ONLY_FULL_GROUP_BY
更稳妥的做法:重写 SQL,而不是关模式
关掉 ONLY_FULL_GROUP_BY 能让旧 SQL 跑通,但会掩盖语义风险。例如:
SELECT id, name FROM user GROUP BY dept_id;
MySQL 可能随机返回每个部门的某条 id/name,下次执行结果可能完全不同——API 返回、报表导出、定时任务都可能因此出错。
- 如果要取每个分组的最新一条,用
MAX(id)或子查询 +ROW_NUMBER()(MySQL 8.0+) - 如果要拼接多值,用
GROUP_CONCAT(name)而不是裸选name - 如果只是去重,
DISTINCT比GROUP BY更轻量、意图更清晰
真正难的不是怎么关限制,而是判断哪些字段“逻辑上属于分组代表”——这得看业务含义,没法靠配置自动解决。



















