laravel Eloquent 中的嵌套“AND OR”查询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25129117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 16:40:16  来源:igfitidea点击:

Nested 'AND OR' Query in Eloquent

laravellaravel-4eloquent

提问by Kevin

I'm currently attempting to create a nested query, as follows:

我目前正在尝试创建一个嵌套查询,如下所示:

public function getChallenge($user_id, $opponent_id)
{
    $challenge = $this->challenges()
            ->where('open', true)
            ->where(function($query) use ($user_id, $opponent_id) {
                    $query->where('player_1', $user_id)
                          ->where('player_2', $opponent_id);
                })
                 ->orWhere(function($query) use ($opponent_id, $user_id) {
                    $query->where('player_1', $opponent_id)
                          ->where('player_2', $user_id);
                })
            ->first();

    return $challenge;
}

This creates the following query for example:

例如,这将创建以下查询:

select * from `site_challenges_leagues` 
where `site_challenges_leagues`.`league_id` = '1' 
and `open` = '1'
and (`player_1` = '3' and `player_2` = '1') 
or (`player_1` = '1' and `player_2` = '3') 
limit 1

However, this always returns the first value in the table (where openis either 1or 0), which is incorrect. For the query to be correct, it needs to contain both sets of ANDqueries in brackets, as follows:

但是,这总是返回表中的第一个值(其中open10),这是不正确的。为了使查询正确,它需要AND在括号中包含两组查询,如下所示:

 select * from `site_challenges_leagues` 
 where `site_challenges_leagues`.`league_id` = '1' 
 and `open` = TRUE 

 and ((`player_1` = '3' and `player_2` = '1') 
 or (`player_1` = '1' and `player_2` = '3'))

 limit 1

Is it possible to do this in Laravel? I attempted to do this; however, it failed:

可以在 Laravel 中做到这一点吗?我试图这样做;然而,它失败了:

public function getChallenge($user_id, $opponent_id)
{
    $challenge = $this->challenges()
            ->where('open', true)
            ->where(function($q) use ($user_id, $opponent_id) {
                $q->where(function($query) {
                        $query->where('player_1', $user_id)
                              ->where('player_2', $opponent_id);
                    })
                  ->orWhere(function($query) {
                        $query->where('player_1', $opponent_id)
                              ->where('player_2', $user_id);
                    })
                })
            ->first();

    return $challenge;
}

Any help is greatly appreciated.

任何帮助是极大的赞赏。

回答by Razor

You were very close to the answer

你非常接近答案

$challenge = $this->challenges()
        ->where('open', true)
        ->where(function($q) use ($user_id, $opponent_id) {
            $q->where(function($query) use ($opponent_id, $user_id){
                    $query->where('player_1', $user_id)
                          ->where('player_2', $opponent_id);
                })
              ->orWhere(function($query) use ($opponent_id, $user_id) {
                    $query->where('player_1', $opponent_id)
                          ->where('player_2', $user_id);
                });
            })
        ->first();

Hereare the differences between two codes

是两个代码之间的区别

回答by Gabi Dj

I needed the nested wheres to search for a user by multiple fields:

我需要嵌套的 wheres 来按多个字段搜索用户:

    $users_query->where('company_uuid', '=', $company_uuid);
    $users_query->where('is_active', '=', true);
    $users_query->whereNested(function($query) use ($search){
        /** @var Builder $query */
        $query
            ->where('first_name', 'like', '%' . $search . '%')
            ->orWhere('last_name', 'like', '%' . $search . '%')
            ->orWhere('email', 'like', '%' . $search . '%');
    });

Supposing you want to stack wherelayers without losing them on using orWhereWouldn't this be the same thing ?

假设您想where在使用时不丢失图层的情况下堆叠图层,orWhere这不是一回事吗?

   $challenge = $this->challenges()
       ->where('open', true)
       ->whereNested(function($q) use ($user_id, $opponent_id) {
           $query->where('player_1', $user_id)
               ->where('player_2', $opponent_id);

           $query->orWhere('player_1', $opponent_id)
               ->where('player_2', $user_id);
   })->first();