在另一个表 Laravel 中查找具有数据透视表中所有 id 的记录

Posted

技术标签:

【中文标题】在另一个表 Laravel 中查找具有数据透视表中所有 id 的记录【英文标题】:Find records which has all ids in pivot table in another table Laravel 【发布时间】:2021-12-08 18:36:24 【问题描述】:

在我的 laravel 项目中,我的表格如下所示。

groupsusers 是多对多关系,这意味着一个用户可以属于多个组。

group_user 表是中间表,表示哪个用户属于哪个组。

slot_votes 表记录用户对 slot 的投票。它与groups table 的关系是groups table hasMany slot_votes

groups

|id | channel_id   |
+---+---------+
|1  |  U124  |
|2  |  U123  |
|3  |  U125  |
|4  |  U127  |

users

|id | name   |
+---+---------+
|1  |  A  |
|2  |  B  |
|3  |  C  |
|4  |  D  |

group_user

|id | group_id | user_id   |
+---+----------+-----------+
|1  |     1    |     1     |
|2  |     2    |     1     |
|3  |     2    |     2     |
|4  |     3    |     3     |
|5  |     4    |     3     |
|6  |     1    |     4     |

slot_vote

|id | user_id | group_id  |    slot   |
+---+---------+-----------+-----------+
|1  |     1   |     1     |     A     |
|2  |     2   |     1     |     B     |
|3  |     2   |     2     |     C     |
|1  |     1   |     4     |     C     |

我的问题是如何使用 Laravel Eloquent 获取所有成员都投票的组 ID?

例如,如果组 1 的成员是 $userId = [1, 4] 并且用户 1 和 4 都已投票(因此存在于 slot_votes 表中),我想在结果中获取组 1 id。

我尝试过的:

    Group::whereHas('users', function ($query, $votedUser) 
        $query->whereIn(
            'id',
            SlotVote::where('group_id', $groupId)->pluck('user_id')->unique()
        );
    , '=', count($votedUser))->get();

但我不知道如何在whereIn 子句中获取$groupId。另外,我担心查询性能。关于如何获得所需结果的任何想法?

先谢谢你了。

【问题讨论】:

如果您关心性能并且想在一个查询中完成所有操作,我建议从 Group 模型开始使用 leftJoin()。加入 group_userslot_vote 并比较两个计数:COUNT(group_user.user_id)COUNT(slot_vote.user_id) 感谢您的回复。现在就试试。您知道如何使用多个查询来做到这一点吗? 子选择怎么样? 通过两个查询,您可以通过group_user 表上的 SELECT COUNT(user_id) 和 GROUP BY group_id 获取每个组的用户数。另一个查询在slot_vote 表上执行相同操作,然后为每个 group_id 比较两个查询的计数用户。但是这样做并在结果集合上执行 php 搜索比在一个使用 JOIN 的查询中执行的性能要差 @ZarkDev 我也想知道有没有办法使用 Eloquent ORM?在这种情况下使用 ORM 而不是查询构建器更好吗? 【参考方案1】:

我设法使用以下代码解决了这个问题:

Group::leftJoin('group_user', 'groups.id', '=', 'group_user.group_id')
                    ->leftJoin('slot_votes', 'group_user.user_id', '=', 'slot_votes.user_id')
                    ->selectRaw(
                        "groups.id, channel_id,
                        count(distinct group_user.user_id) as members,
                        count(distinct slot_votes.user_id) as voted_members",
                    )
                    ->groupBy('groups.id')
                    ->havingRaw('members=voted_members')
                    ->get();

【讨论】:

以上是关于在另一个表 Laravel 中查找具有数据透视表中所有 id 的记录的主要内容,如果未能解决你的问题,请参考以下文章

如何获取已存储在另一个模型中的名称 ID,并使用名称 ID 在 laravel 的数据透视表数据库中存储值?

在 Laravel 的数据透视表中添加 id 列有啥好处?

在 laravel 的数据透视表中存储数据

laravel4 更新数据透视表中的附加列

laravel 多对多关系不存储在数据透视表中

Laravel 根据数据透视表从表中获取标题