如何在 Laravel 中使用ID作为主键在查询中进行表联接

3

我想做一个基于两个数据库表进行过滤的函数。然而,我不确定如何在查询中放置联接表。这意味着在将结果返回给数据表之前,将从两个表(用户和员工表)过滤数据。

我的过滤查询是:

public function filterQuery(Request $request){

    $age = $request->age;
    $gender= $request->gender;

    $query = user::query();

    if(!empty($request->age)){
        $query->where('age','>=',$age );
    }

    if(!empty($request->gender)){
        $query->where('gender','<=',$gender);
    }

    $data = $query->get();

    return datatables()->of($data)->make(true);
}

我想要在查询中连接的表来自员工表(列 = 收入和住房所有权)。连接这两个表的主键是IC。


这些表之间有什么关系?年龄和性别是用户列还是员工列? - TsaiKoga
年龄和性别来自用户表。同时,收入和房屋所有权来自员工表。它们通过IC作为主键连接。 - swm
所以雇员和用户是一对一的关系吗?您在两个模型中都建立了这种关系吗? - TsaiKoga
在employee.php中加入类似于这样的代码:return $this->hasOne('App\user');。 - swm
3个回答

2
如果你的模型之间存在关联,你可以使用whereHas
    if(!empty($request->income) || !empty($request->house_ownership)){
        $query->whereHas('employee', function($q) use ($income, house_ownership) {
             if (!empty($income)) {
                  $q->where('income', $income);
             }
             if (!empty($house_ownership)) {
                  $q->where('house_ownership', $house_ownership);
             }             
        });
    }
...

或者您可以使用join或leftjoin来过滤另一个表:

public function filterQuery(Request $request){

    $age = $request->age;
    $gender= $request->gender;
    $house_ownership = $request->house_ownership;
    $income= $request->income;

    $query = user::query();
    $query->leftjoin('employee', 'employee.IC', '=', 'user.IC');

    if(!empty($request->age)){
        $query->where('user.age','>=',$age );
    }

    if(!empty($request->gender)){
        $query->where('user.gender','<=',$gender);
    }

    if(!empty($request->income)){
        $query->where('employee.income', $income);
    }
    if(!empty($request->house_ownership)){
        $query->where('employee.house_ownership', $house_ownership);
    }
    $data = $query->select('user.*')->get();

    return datatables()->of($data)->make(true);
}

如果(!empty($request->income)){ $query->where('employee.income',$income);不起作用(以及house_ownership),你知道为什么吗? - swm
@wns,你已经按照上面的代码加入了员工表吗?有出现错误信息吗? - TsaiKoga
控制台没有错误。当我独立按表格筛选(例如仅按性别和年龄或收入和房屋所有权筛选)时,它可以正常工作。但是当我将年龄/性别与收入/房屋所有权一起筛选时,我的数据表格就没有结果(没有可用数据)。 - swm
@wns 你确定数据库中存在年龄/性别与收入/房屋所有权记录吗?而且 $query->where('employee.income', $income); 表示员工收入等于请求的收入,如果你想要范围,可以使用大于或小于... - TsaiKoga
@wns 另外一件事是 Laravel 的 join 表示的是 innerjoin,也许你需要使用 leftjoin,这样即使没有员工,用户记录仍然会显示。我已经更新了我的答案为 leftjoin - TsaiKoga

1
尝试这个。
public function filterQuery(Request $request){

    $age = $request->age;
    $gender= $request->gender;
    if(!empty($request->age)){
       $data = User::where('age','>=',$age)->get();
    }

    if(!empty($request->gender)){
      $data =  User::where('gender','<=',$gender)->get();
    }


    return datatables()->of($data)->make(true);
}

1
你可以使用Eloquent::when()来减少条件查询中的if-else语句。
public function filterQuery(Request $request){

    $query = user::query();
    $query->select('user.*')->join('employee', 'employee.IC', '=', 'user.IC');

    $data = $query
        ->when(request('age') != null , function ($q) {
            return $query->where('user.age','>=',request('age'));
        })
        ->when(request('gender') != null , function ($q) {
            return $query->where('user.gender','<=',request('gender'));
        })
        ->when(request('income') != null , function ($q) {
            return $query->where('employee.income','<=',request('income'));
        })
        ->when(request('house_ownership') != null , function ($q) {
            return $query->where('employee.house_ownership','<=',request('house_ownership'));
        })
    ->get();

    return datatables()->of($data)->make(true);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接