You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 5.8 Query Builder分组失效求助:如何按table_name分组

解决Laravel Query Builder分组未生效的问题

看起来你遇到的问题是同时按两个字段分组导致结果不符合预期——你当前的groupBy('c.key', 'c.table_name')会把key和table_name的组合作为分组依据,只有当这两个字段完全匹配的行才会被归为一组,这就导致即使table_name相同,只要key不同,就会生成独立的分组。

下面分两种场景给出解决方案:

场景1:仅按table_name分组,聚合关联的key

如果你的需求是每个table_name只出现一次,同时需要获取该分组下的所有key,可以用MySQL的聚合函数(比如GROUP_CONCAT)来合并key,并只按table_name分组:

$data['list_module'] = DB::table('roles as a')
    ->leftJoin('permission_role as b', 'a.id', 'b.role_id')
    ->leftJoin('permissions as c', 'b.permission_id', 'c.id')
    ->where('a.id', $id)
    // 选择table_name,并用GROUP_CONCAT聚合同一分组下的所有唯一key
    ->select('c.table_name', DB::raw('GROUP_CONCAT(DISTINCT c.key) as permission_keys'))
    // 仅按table_name分组
    ->groupBy('c.table_name')
    ->orderBy('c.table_name', 'DESC')
    ->get();

这段代码会返回每个table_name对应的一行数据,permission_keys字段是该分组下所有key用逗号分隔的字符串。如果需要把permission_keys转为数组,可以在获取结果后处理:

$data['list_module'] = $data['list_module']->map(function ($item) {
    $item->permission_keys = explode(',', $item->permission_keys);
    return $item;
});

场景2:保留所有key,但在结果集中按table_name分组展示

如果你的需求是保留所有key数据,只是在逻辑上按table_name分组,可以先获取全部数据,再用Laravel集合的groupBy方法处理:

// 先获取所有原始数据
$rawPermissions = DB::table('roles as a')
    ->leftJoin('permission_role as b', 'a.id', 'b.role_id')
    ->leftJoin('permissions as c', 'b.permission_id', 'c.id')
    ->where('a.id', $id)
    ->select('c.key','c.table_name')
    ->orderBy('c.table_name', 'DESC')
    ->get();

// 用集合的groupBy方法按table_name分组
$data['list_module'] = $rawPermissions->groupBy('table_name');

最终$data['list_module']会是一个集合,键为table_name的值,对应的值是该分组下所有包含key和table_name的对象数组。

额外提醒:MySQL严格模式注意事项

如果你的Laravel项目开启了MySQL严格模式(默认是开启的),groupBy必须遵循ONLY_FULL_GROUP_BY规则:select中的字段要么出现在groupBy里,要么是被聚合函数处理过的字段。上面的两种方案都符合这个规则,不会触发报错。

内容的提问来源于stack exchange,提问作者Rahmat Effendi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:14:05