← 中文资源

简体中文版本

MySQL ERROR 1055 — ONLY_FULL_GROUP_BY 拒绝查询

通过对所有未聚合的查询列进行分组或聚合,并避免关闭 ONLY_FULL_GROUP_BY 来掩盖非法 SQL,修复 MySQL 1055。

阅读英文原文

症状

本篇指南处理“MySQL ERROR 1055 — ONLY_FULL_GROUP_BY 拒绝查询”。请从症状出发,按顺序执行诊断,在推进前确认每个假设;随后通过修复与验证步骤闭环。

可观察到的症状包括:

  • ERROR 1055 (42000): SELECT 列表的第 1 个表达式不在 GROUP BY 子句中
  • 查询在旧版 MySQL 可用,升级到 5.7+/8.0 后失败
  • 向 SELECT 列表新增一列后突然报错

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

mysql -e "SELECT id, COUNT(*) FROM orders GROUP BY status"

错误会指出未分组列的位置;把它加入 GROUP BY 或对其聚合。

步骤 2

mysql -e "SELECT @@sql_mode"

sql_mode 含 ONLY_FULL_GROUP_BY 即解释了宽松查询为何被拒。

常见诱因(按出现频率排序):

  • 所选取的列既未聚合也未列入 GROUP BY
  • 本意是每组取一行代表,但 ONLY_FULL_GROUP_BY 已启用
  • 查询依赖已不再允许的 MySQL 宽松分组行为

根因

启用 ONLY_FULL_GROUP_BY(MySQL 5.7+ 与 8.0 默认)后,SELECT 列表中的每一列必须函数依赖于 GROUP BY 列,或被聚合包裹。这可防止不确定的行。

修复

把列加入 GROUP BY、在可接受某值时用 MIN/MAX/ANY_VALUE 聚合,或用窗口函数/连接重写以每组取一行。

注意:关闭 ONLY_FULL_GROUP_BY 会使结果在不同服务器与版本间不确定;不要为消除错误而关闭它。

-- ❌ id not grouped nor aggregated (ERROR 1055)
-- SELECT status, id FROM orders GROUP BY status;

-- ✅ aggregate a representative value
SELECT status, MIN(id) AS first_id, COUNT(*) AS n
FROM orders
GROUP BY status;

-- ✅ or group all selected columns
SELECT status, id, COUNT(*) FROM orders GROUP BY status, id;

验证

运行重写后的查询并确认每组返回确定性的一行;验证 @@sql_mode 仍包含 ONLY_FULL_GROUP_BY。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。