报错是因MySQL启用了ONLY_FULL_GROUP_BY模式,要求非聚合字段必须出现在GROUP BY中或用聚合函数包裹;可补全GROUP BY字段、用聚合函数、临时禁用模式或永久修改配置,但需权衡数据安全性。
phpMyAdmin 里执行 GROUP BY 报错“not in GROUP BY clause”怎么办
这不是 phpmyadmin 的问题,而是你连接的 mysql(5.7+ 或 8.x)启用了 only_full_group_by 严格模式。报错信息里那串 “expression #1 of select list is not in group by clause…” 就是它在拦你——mysql 要求:所有非聚合字段(比如 name、email)必须出现在 group by 子句里,否则拒绝执行。
直接改 SQL:补全 GROUP BY 字段 or 用聚合函数包裹
这是最安全、兼容性最好的解法,不依赖数据库配置变更,上线后也稳定。
- 如果想按用户分组并查出每个用户的最新订单时间,但又想顺带显示用户名:
❌ 错误写法:SELECT id, name, MAX(created_at) FROM orders JOIN users ON orders.user_id = users.id GROUP BY orders.user_id(name不在GROUP BY里,且没聚合)
✅ 正确写法一(补全):SELECT users.id, users.name, MAX(orders.created_at) FROM orders JOIN users ON orders.user_id = users.id GROUP BY users.id, users.name
✅ 正确写法二(聚合):SELECT users.id, MAX(users.name), MAX(orders.created_at) FROM orders JOIN users ON orders.user_id = users.id GROUP BY users.id(注意:MAX(name)在 name 唯一时才等价,否则语义可能偏移) - 如果分组字段是主键(如
users.id),MySQL 认为其他字段函数依赖于它,此时SELECT id, name, email FROM users GROUP BY id是合法的——但仅限于 InnoDB 表且该字段确实被主键唯一确定。
临时绕过:在 phpMyAdmin 当前会话里关掉 ONLY_FULL_GROUP_BY
适合调试或临时查数据,不能用于生产环境逻辑,且重启连接就失效。
- 在 phpMyAdmin 的 SQL 标签页,先运行:
SELECT @@sql_mode;确认是否含ONLY_FULL_GROUP_BY - 再执行:
SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); - 之后同一窗口里的查询就不再校验该规则了。但注意:这只是当前连接有效,换一个标签页或刷新页面就得重设。
永久禁用 ONLY_FULL_GROUP_BY(慎用)
修改 MySQL 配置本质是降低数据语义安全性,容易让“随机返回某一行值”变成常态,尤其当分组内存在多值时(比如同 group 有多个 status),SELECT status FROM t GROUP BY category 可能每次返回不同值。
- 编辑 MySQL 配置文件(
my.cnf或my.ini),在[mysqld]段下添加:sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION(去掉ONLY_FULL_GROUP_BY) - 重启 MySQL 服务生效。但需同步检查 Laravel 或其他应用是否依赖严格模式做数据一致性保障——比如某些 Eloquent 关联聚合查询会隐含依赖该行为。
真正难的不是让查询跑通,而是判断哪一列值在分组内是否“必然唯一”。比如用 ANY_VALUE(name) 能强行绕过检查,但它不解决语义歧义——你得自己确认这个 name 在当前分组里确实不会变。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











