【问题标题】:How to query an Eloquent ORM many-to-many relationship如何查询 Eloquent ORM 多对多关系
【发布时间】:2023-04-01 11:24:01
【问题描述】:

我有在各州(即澳大利亚各州)工作的员工。

员工存储在 users 表中。状态存储在状态表中。两者之间的多对多关系存储在staff_state中。

在我的 Staff 模型上,我有一个方法如下:

public function workStates()
{
    return $this->belongsToMany(Core\State::class);
}

我想检索在 NSW 州工作并且名字或姓氏中包含字母“dan”的所有用户。这是我的 Eloquent 查询:

    $query = Staff::whereHas('workStates', function ($query) {
            $query->where('state_id', '=', 'NSW');})
        ->where('first_name', 'like', '%dan%')
        ->orWhere('last_name', 'like', '%dan%')
        ->orderBy('first_name', 'asc')
        ->orderBy('last_name', 'asc');

我的查询结果都包含字母“dan”,但是有些员工不在新南威尔士州工作。我做错了什么?

这是 Eloquent 生成的 SQL 查询:

select * from `users` where (exists 
    (select * from `states` inner join `staff_state` on `states`.`id` = `staff_state`.`state_id` 
        where `users`.`id` = `staff_state`.`staff_id` and `state_id` = 'NSW') 
    and `first_name` like '%dan%' or `last_name` like '%dan%') 
    and `users`.`deleted_at` is null order by `first_name` asc, `last_name` asc

谢谢..!

【问题讨论】:

    标签: mysql sql laravel eloquent


    【解决方案1】:

    我会尝试将first_namelast_name 条件分组。

    我认为您可以通过将闭包传递给where() 函数来做到这一点。也许是这样的:

    Staff::whereHas('workStates', function ($query) {
        $query->where('state_id', '=', 'NSW');
    })->where(function($query) {
        $query
            ->where('first_name', 'like', '%dan%')
            ->orWhere('last_name', 'like', '%dan%');
    })->orderBy('first_name', 'asc')->orderBy('last_name', 'asc');
    

    【讨论】:

      【解决方案2】:

      您不应该使用state_id,而是使用states 表中的真实列名。 此外,where() closure 中的组名相关逻辑。例如,如果列名是name

      $state = 'NSW';
      $name = 'dan';
      Staff::whereHas('workStates', function ($query) use($state) {
              $query->where('name', $state);
          })
          ->where(function($query) use($name) {
              $query->where('first_name', 'like', '%' . $name . '%')
                    ->orWhere('last_name', 'like', '%' . $name . '%');
          })
          ->orderBy('first_name', 'asc')
          ->orderBy('last_name', 'asc')
          ->get();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-19
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-03
        相关资源
        最近更新 更多