Laravel Eloquent查询报GROUP BY错误 生成SQL手动执行正常
问题根因
出现「Eloquent执行报1055 GROUP BY错误,但日志打印的SQL手动执行正常」的核心原因,是Laravel连接MySQL的会话级sql_mode配置,和你手动操作数据库时的会话sql_mode配置不一致。
MySQL的1055错误由ONLY_FULL_GROUP_BY校验规则触发:当该规则开启时,SELECT查询返回的所有非聚合计算字段,必须全部包含在GROUP BY子句中,否则判定为语法错误。你的查询默认用select *拉取三表关联后的所有字段,但GROUP BY仅指定了crash_info.crash_group_id,严格模式下本身就不符合SQL语法规范。
你手动执行SQL不报错,是因为你当前登录数据库的会话没有开启ONLY_FULL_GROUP_BY校验,MySQL会兼容这种非严谨的GROUP BY写法直接返回结果;而Laravel在建立数据库连接时,会按照框架默认配置自动设置会话级sql_mode,默认开启严格模式(包含ONLY_FULL_GROUP_BY校验),因此执行查询时会触发错误。
少数场景下该问题也可能是你手动连接的数据库实例、库名和Laravel配置的不一致,不同实例的全局sql_mode配置存在差异导致。
解决方案
- 推荐方案(符合SQL规范,无兼容性风险):调整查询逻辑,废弃
select *写法,明确声明需要查询的字段,同时将SELECT中所有非聚合字段加入GROUP BY子句。由于你关联的crash_groups.crash_group_id和crash_info.crash_group_id是外键关联、值完全一致,也可以直接按主表主键分组,示例代码:
$issues = \DB::table('crash_groups') ->join('projects', 'projects.project_id', '=', 'crash_groups.project_id') ->join('crash_info', 'crash_info.crash_group_id', '=', 'crash_groups.crash_group_id') ->where('projects.organisation_id', $organisation_id) ->where('crash_info.created_at', '>', $time_interval_sql) // 按实际业务需要指定查询字段,禁止无意义的select * ->select('crash_groups.*', 'projects.project_name', 'crash_info.last_crash_time') ->groupBy('crash_groups.crash_group_id') ->get();
- 临时兼容方案:如果业务上暂时无法调整查询逻辑,可以修改Laravel数据库配置,关闭
ONLY_FULL_GROUP_BY校验。打开项目下config/database.php文件,找到mysql连接的配置段,在modes配置中移除ONLY_FULL_GROUP_BY项:
'mysql' => [ // 其余配置项保持不变 'strict' => true, 'modes' => [ 'STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_DIVISION_BY_ZERO', 'NO_AUTO_CREATE_USER', 'NO_ENGINE_SUBSTITUTION', // 移除'ONLY_FULL_GROUP_BY'这一项即可关闭对应校验 ], ],
注意:该方案只是绕过了语法校验,非严谨的GROUP BY写法在关联数据存在重复时可能返回不确定的结果,非必要不推荐长期使用。
- 排查项:先核对Laravel的
.env文件中DB_HOST、DB_PORT、DB_DATABASE配置,确认和你手动执行SQL时连接的数据库实例完全一致,排除连错库导致的配置差异问题。
内容的提问来源于stack exchange,提问作者Boardy
相关产品推荐
相关产品推荐

