Laravel5出现SQLSTATE[42000]错误:GROUP BY语法问题求助
解决Laravel 5中GROUP BY引发的SQLSTATE[42000] 1055错误
这个错误的根源是MySQL的ONLY_FULL_GROUP_BY模式在起作用——它要求SELECT语句里的所有非聚合列(也就是没用到SUM、GROUP_CONCAT这类函数的列)必须出现在GROUP BY子句里。你的查询里选了sells.*(包含sells.xid等一堆列),但只GROUP BY了sells.ticket_number,自然触发了这个严格校验。
下面给你几种可行的解决思路:
方法一:关闭MySQL的严格分组校验(快速解决)
如果你不需要严格遵循SQL标准,或者项目里其他查询也有类似情况,可以修改Laravel的数据库配置:
- 打开项目根目录下的
config/database.php - 找到
connections.mysql配置块,把strict选项改成false:
'mysql' => [ // ... 其他配置 'strict' => false, ],
或者更精准地,只移除ONLY_FULL_GROUP_BY模式:
'mysql' => [ // ... 其他配置 'modes' => [ 'STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_DIVISION_BY_ZERO', 'NO_AUTO_CREATE_USER', 'NO_ENGINE_SUBSTITUTION', ], ],
这样MySQL就不会再强制要求非聚合列必须在GROUP BY里了。
方法二:调整查询语句,符合严格分组规则(推荐,更规范)
遵循SQL标准来修改你的查询,确保所有非聚合列都出现在GROUP BY里,或者只选择你实际需要的列:
比如你原来的查询可以改成明确列出需要的sells列,而不是用*,然后把这些列都加到GROUP BY中:
$buyLists = Sell::join('items', 'sells.item_id', '=', 'items.item_id') ->select( 'sells.ticket_number', 'sells.created_at', // 这里列出你实际需要的其他sells列 DB::raw('GROUP_CONCAT(items.item_title SEPARATOR ", ") AS item_titles') ) ->where('sells.created_at', 'like', '2018-04-14%') ->groupBy('sells.ticket_number', 'sells.created_at') // 所有非聚合列都要加进来 ->get();
或者如果你确实需要sells.*,那就要把sells表的所有列都加到GROUP BY里,但这样可能不符合你的业务逻辑(因为同ticket_number可能有不同的其他列值),所以更建议只选需要的列。
方法三:使用子查询先处理聚合,再关联
如果同一张票对应多个商品,你可以先通过子查询把每个ticket_number对应的商品标题拼接好,再和sells表关联:
$itemTitles = DB::table('sells') ->join('items', 'sells.item_id', '=', 'items.item_id') ->select( 'sells.ticket_number', DB::raw('GROUP_CONCAT(items.item_title SEPARATOR ", ") AS item_titles') ) ->groupBy('sells.ticket_number'); $buyLists = Sell::select('sells.*', 'item_titles') ->joinSub($itemTitles, 'item_titles_sub', function ($join) { $join->on('sells.ticket_number', '=', 'item_titles_sub.ticket_number'); }) ->where('sells.created_at', 'like', '2018-04-14%') ->get();
这种方式既满足了GROUP BY的规则,又能拿到sells的所有字段。
内容的提问来源于stack exchange,提问作者Mingeun Kim
相关产品推荐
相关产品推荐

