【问题标题】:Group records by relation按关系分组记录
【发布时间】:2015-01-22 22:08:53
【问题描述】:

我有模型,UserGroup,在 many to many 相关性中。用户可能有 0 个与之关联的组。我需要返回按组分组的所有用户,还有那些没有组的用户,如下所示:

所有用户列表

  • 第 1 组
    • 用户 1
    • 用户 2
  • 第 2 组
    • 用户 3
    • 用户 4
  • 未分组
    • 用户 5
    • 用户 6

我试过用这个:

$groups = $this->group->all();

foreach($groups as $group) {
    echo $group->name;
    foreach($group->users as $user) {
        echo $user->name;
    }
}

但这只会返回属于某个组的用户。

Laravel 有什么优雅的方式来完成这个吗?

【问题讨论】:

    标签: php laravel eloquent grouping


    【解决方案1】:

    本机没有,但你也可以用 laravel 的方式来做。

    示例:

    $groups = Groups::with('users')->all();
    
    foreach($groups as $group){
        echo $group->name;
        foreach($group->users as $user){
            echo $user->name;
        }
    }
    
    $usersWithoutGroups = User::has('groups', '<', 1)->get();
    echo 'Without Groups';
    foreach($group->users as $user){
        echo $user->name;
    }
    

    【讨论】:

    • 感谢马克西米利安,我怎么能把这两个结果结合起来得到['Group 1' =&gt; ['User 1', 'User 2'], 'Group 2' =&gt; ['User 3', 'User 4'], 'No Group' =&gt; ['User 5', 'User 6']]
    【解决方案2】:

    我不认为 Eloquent 有什么好的方法可以做到这一点,因为它并不能真正解释这些类型的场景,即您试图从不存在关系的关系中获取结果。您可以使用has() 加载结果为 0 的关系,但如果那里没有可开始的组,那对您没有多大用处。

    我建议使用查询生成器,这种类型的事情可以在单个查询中完成,使用左连接并在空值上合并以返回“未分组”。

    $results = DB::table('users')
        ->selectRaw('group_concat(users.name) as user_list, coalesce(groups.name, \'Ungrouped\') as group_name')
        ->leftJoin('group_user', 'group_user.user_id', '=', 'users.id')
        ->leftJoin('groups', 'groups.id', '=', 'group_user.group_id')
        ->groupBy('groups.name')
        ->get();
    
    foreach($results as $result) {
        echo $result->group_name;
        $users = explode(',', $result->group_name);
        foreach($users as $user) {
            echo $user;
        }
    }
    

    【讨论】:

    • user3158900 感谢您的宝贵时间。出于某种原因,我在echo $user-&gt;name; 上收到了Trying to get property of non-object。如果我只做echo $user;,我只会得到string(9) "Ungrouped" string(12) "Test Group 1"。这可能是什么原因?
    • 哦,对不起,愚蠢的错误。 Explode 返回一个数组,而不是一个对象。那应该给你你所有的组。尝试在末尾删除-&gt;get(),然后尝试-&gt;toSql() 并回显结果。它应该为您提供可以手动运行以查看结果的 sql。
    猜你喜欢
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    • 2015-01-30
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多