ThinkPHP 多对多关联如何条件查询?

三张表(用户表、部门表、中间表:user_has_departments)
用户可以隶属多个部门,所以定义了多对多关系。
中间表:id,user_id,department_id

关联关系

    // 用户模型下定义
    public function departments()
    {
        return $this->belongsToMany(Department::class, 'user_has_departments', 'department_id', 'user_id');
    }

    // 部门模型相对定义
    public function user()
    {
        return $this->belongsToMany(Users::class,'user_has_departments', 'user_id', 'department_id');
    }

需求

根据传入的部门ID集合,查询出所属用户列表。
传入的部门ID如[2,5,6,7],所以是一次查询多个部门,ThinkPHP的多对多好像不支持hasWhere,所以不知道怎么查询,请大神解答。

我目前的做法(实现最终需求但感觉Low,所以来提问)

    // 直接Db查询中间表获得user_id集合
    $userIds = Db::name('user_has_departments')
            ->whereIn('department_id',[2,5,6,7])
            ->column('user_id');
    // 然后再从user表in查询用户(我这个是写在搜索器里的,所以返回的是$query)
    return $query->whereIn('id', $userIds);
php
讨论数量: 8
Department::WhereIn('id',[2,5,6,7])->with('user')->get();
2年前 评论

@lyxxxh 小哥,这样不对,这是查询出部门数据并管理那预载入他的user哈。我要的是[2,5,6,7]部门里的所有用户ID

2年前 评论
$department_id = ['1', '2'];
$data = (new User())
    ->withCount([
        'userhasdepartments' => function ($userhasdepartments) use ($department_id) {
            $userhasdepartments->whereIN('department_id', $department_id);
        }
    ])
    ->having('userhasdepartments_count>0')
    ->select();
2年前 评论

@aichen521001 首先说学到了新知识小哥,但是还是不太对,不太明白。

我是要在thinkphp的搜索器里写:

// User模型定义了一个搜索器,可以根据部门ID查询部门下的所属用户
public function searchDepartmentIdAttr($query, $value, $data){
    // $value是传过来查询的条件 假设$value是[2,5,6,7]。
    // 如果用户只隶属于一个部门,那用户表冗余一个department_id字段,然后返回下面就行了,但是
    // return $query->whereIn('department_id', $value);

   // 但是我是用户列属于多个部门,所以有个中间表 user_has_departments ,多对多belongsToMany。
   // 用我文中最后的写法,先用db查询出中间表的所有用户id,然后whereIn用户表是可以,但是我想寻求另外更聪明或者更高级的写法,就不会了。
    // 从中间表查询出所有用户id,
    $userIds = Db::name('user_has_departments')
            ->whereIn('department_id',[2,5,6,7])
            ->column('user_id');
    // 然后再从user表in查询用户(我这个是写在搜索器里的,所以返回的是$query)
    return $query->whereIn('id', $userIds);
}
2年前 评论
ztongxue 1年前

做过类似的

$department_id = ['1', '2'];

$list = Departments::whereIN('department_id', $department_id)->all()->each(function($model){
$model->user()->where(用户查询条件)->all();
});
1年前 评论
PHPisGod 1年前
kevin0601 (作者) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!