一条在旧库跑得好好的统计 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 的查询构造器配置,通常有开关可以自动补全分组字段。