Laravel Eloquent 多个 wheres 给出了错误的结果
Laravel Eloquent multiple wheres gives wrong results
为什么下面这段代码返回错误结果?
$player->wins = Game::where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id)
->where('result', '=','1') // 1 = win
->get();
$player->losses = Game::where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id)
->where('result', '=','0') // 0 = lose
->get();
$player->matches = Game::where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id)
->get();
我得到的是 5 场比赛/5 胜/5 负,而实际上是 5/5/0。我应该怎么做?
查看 Laravel 文档中关于 Logical Grouping 的 post。我认为基于此,您对 matches
的陈述应该是:
$player->matches = Game::where(function ($query) use ($player) {
$query->where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id);
})->get();
我不确定这是否有帮助,因为我没有其余的代码,但请测试它并告诉我。
同样来自文档:
"In fact, you should generally always group calls to the orWhere method in parentheses in order to avoid unexpected query behavior."
将您的 home_player_x
子句移动到 嵌套的 where 条件子句中:
$player->wins = Game::where(function ($query) use ($player) {
return $query->where('home_player_1', $player->id)
->orWhere('home_player_2', $player->id)
->orWhere('home_player_3', $player->id)
->orWhere('home_player_4', $player->id);
})->where('result', 1)
->get();
...
这样,它就不会与最后一个 ->where('result')
子句冲突。
此外,由于您多次重复使用此子句,请将其定义为变量并重复使用:
$conditional = function ($query) use ($player) {
return $query->where(function ($subQuery) use ($player) {
return $subQuery->orWhere('home_player_1', $player->id)
->orWhere('home_player_2', $player->id)
->orWhere('home_player_3', $player->id)
->orWhere('home_player_4', $player->id);
})
});
$player->wins = Game::where($conditional)->where('result', 1)->get();
$player->losses = Game::where($conditional)->where('result', 0)->get();
$player->matches = Game::where($conditional)->get();
或者,考虑将其定义为 Game
模型上的作用域,这样您就可以调用 Game::playerMatches($player)->where('result', 1)->get()
,等等。请参阅相关文档:
https://laravel.com/docs/8.x/eloquent#local-scopes
我不会对此过多提及,但定义编号列,如 home_player_1
、home_player_2
等通常被认为是不良数据实践。您应该定义 home_players
table 或 games_players
,并为 home
或 away
table 定义一个 type
列并关联 Game
和 Players
这样。
需要修改 orWhere() 条件,而不是上面你可以使用下面的 where 子句:
$player->wins = Game::where('result', '=','1') // 1 = win
->where(function ($query) use ($player) {
$query->where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id);
})->get();
$player->losses = Game::where('result', '=', '0') // 0 = lose
->where(function ($query) use ($player) {
$query->where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id);
})->get();
$player->matches = Game::
where(function ($query) use ($player) {
$query->where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id);
})->get();
当有多个orWhere()时,正常情况下不行,需要在单个where下添加。
为什么下面这段代码返回错误结果?
$player->wins = Game::where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id)
->where('result', '=','1') // 1 = win
->get();
$player->losses = Game::where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id)
->where('result', '=','0') // 0 = lose
->get();
$player->matches = Game::where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id)
->get();
我得到的是 5 场比赛/5 胜/5 负,而实际上是 5/5/0。我应该怎么做?
查看 Laravel 文档中关于 Logical Grouping 的 post。我认为基于此,您对 matches
的陈述应该是:
$player->matches = Game::where(function ($query) use ($player) {
$query->where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id);
})->get();
我不确定这是否有帮助,因为我没有其余的代码,但请测试它并告诉我。
同样来自文档:
"In fact, you should generally always group calls to the orWhere method in parentheses in order to avoid unexpected query behavior."
将您的 home_player_x
子句移动到 嵌套的 where 条件子句中:
$player->wins = Game::where(function ($query) use ($player) {
return $query->where('home_player_1', $player->id)
->orWhere('home_player_2', $player->id)
->orWhere('home_player_3', $player->id)
->orWhere('home_player_4', $player->id);
})->where('result', 1)
->get();
...
这样,它就不会与最后一个 ->where('result')
子句冲突。
此外,由于您多次重复使用此子句,请将其定义为变量并重复使用:
$conditional = function ($query) use ($player) {
return $query->where(function ($subQuery) use ($player) {
return $subQuery->orWhere('home_player_1', $player->id)
->orWhere('home_player_2', $player->id)
->orWhere('home_player_3', $player->id)
->orWhere('home_player_4', $player->id);
})
});
$player->wins = Game::where($conditional)->where('result', 1)->get();
$player->losses = Game::where($conditional)->where('result', 0)->get();
$player->matches = Game::where($conditional)->get();
或者,考虑将其定义为 Game
模型上的作用域,这样您就可以调用 Game::playerMatches($player)->where('result', 1)->get()
,等等。请参阅相关文档:
https://laravel.com/docs/8.x/eloquent#local-scopes
我不会对此过多提及,但定义编号列,如 home_player_1
、home_player_2
等通常被认为是不良数据实践。您应该定义 home_players
table 或 games_players
,并为 home
或 away
table 定义一个 type
列并关联 Game
和 Players
这样。
需要修改 orWhere() 条件,而不是上面你可以使用下面的 where 子句:
$player->wins = Game::where('result', '=','1') // 1 = win
->where(function ($query) use ($player) {
$query->where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id);
})->get();
$player->losses = Game::where('result', '=', '0') // 0 = lose
->where(function ($query) use ($player) {
$query->where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id);
})->get();
$player->matches = Game::
where(function ($query) use ($player) {
$query->where('home_player_1', '=', $player->id)
->orWhere('home_player_2', '=', $player->id)
->orWhere('home_player_3', '=', $player->id)
->orWhere('home_player_4', '=', $player->id);
})->get();
当有多个orWhere()时,正常情况下不行,需要在单个where下添加。