一条在旧库跑得好好的统计 SQL,换到新环境报 1055:SELECT 列表里的列不在 GROUP BY 中,与 only_full_group_by 模式不兼容。MySQL 5.7 之后默认开启严格模式。

先看具体哪一列

错误信息会直接点名 Expression #N,对照 SELECT 列表数一下是哪个字段。它要么补进 GROUP BY,要么用聚合函数包起来。

三种改法

-- 1. 补进分组
SELECT user_id, status, COUNT(*) FROM orders
GROUP BY user_id, status;

-- 2. 明确取值
SELECT user_id, ANY_VALUE(status), COUNT(*) FROM orders
GROUP BY user_id;

-- 3. 用聚合
SELECT user_id, MAX(created_at), COUNT(*) FROM orders
GROUP BY user_id;

ANY_VALUE 只是告诉数据库「随便取一个」,语义上是模糊的,仅在确定同组内该列值一致时使用。

不建议直接关掉严格模式

临时执行 SET sql_mode 去掉该选项能让旧 SQL 跑起来,但这会让其他查询悄悄返回不确定的结果,统计数字对不上时更难排查。

升级前把业务 SQL 全量跑一遍,用测试库开启严格模式做回归,比上线后逐个改要省事。索引也要一起看,补上分组字段的联合索引后,这类统计查询往往能快一个数量级。

有些框架生成的 SQL 会把 SELECT * 带进分组查询,运行到这一步才报错。翻翻 ORM 的查询构造器配置,通常有开关可以自动补全分组字段。

作者 9823189