简体   繁体   English

Laravel where子句在一系列orwhere之后不起作用

[英]Laravel where clause not working after series of orwhere

I have a query that fetches users based on some parameters. 我有一个查询,根据一些参数获取用户。

$users = User::where(function($query) use($queryTags_userIDs) {
    $query->whereIn('id', $queryTags_userIDs);
})->orWhere(function($query) use($queryImageTitles_userIDs) {
    $query->whereIn('id', $queryImageTitles_userIDs);
})->orWhere('username', 'LIKE', "%{$query}%")
    ->orWhere('keywords', 'LIKE', "%{$query}%")     
    ->orWhere('profile_text', 'LIKE', "%{$query}%")
    ->orWhere('tagline', 'LIKE', "%{$query}%")
    ->where('role', 2)
    ->orderBy('last_login', 'desc')
    ->paginate(15);

Now, this whole thing works great. 现在,这一切都很有效。

Except this part: 除此部分外:

->where('role', 2)

Instead of getting users where role is 2, it fetches users of EVERY role. 它不是让角色为2的用户,而是获取每个角色的用户。

However, it WILL work if I get rid of some orWheres. 但是,如果我摆脱一些或者某些东西,它会起作用。

If I get rid of these 3 orWheres: 如果我摆脱这些3或者范围:

->orWhere('keywords', 'LIKE', "%{$query}%")     
->orWhere('profile_text', 'LIKE', "%{$query}%")
->orWhere('tagline', 'LIKE', "%{$query}%")

then it starts fetching users only with role 2. In fact, these 3 specific orWheres are, for whatever reason, causing the problem 然后它开始仅使用角色2获取用户。事实上,无论出于何种原因,这3个特定或者范围都会导致问题

If I reduce the query to only 如果我只将查询减少到

$users = User::where('username', 'LIKE', "%{$query}%")
    ->orWhere('keywords', 'LIKE', "%{$query}%")     
    ->where('role', 2)
    ->orderBy('last_login', 'desc')
    ->paginate(7);

it STILL gets users from outside of role 2. 它仍然从角色2之外获取用户。

However, if it were to switch it to this: 但是,如果要将其切换为:

$users = User::where('username', 'LIKE', "%{$query}%")
    ->where('role', 2)
    ->orderBy('last_login', 'desc')
    ->paginate(7);

then all of a sudden it only gets users from role 2. 然后突然间它只从角色2获得用户。

Why is this happening? 为什么会这样? I feel like I'm missing something super obvious, because this makes no sense. 我觉得我错过了一些非常明显的东西,因为这没有任何意义。

EDIT 编辑

In response to Bassem El Hachem, I put role = 2 at the beginning of the query. 为了回应Bassem El Hachem,我在查询的开头放了role = 2。 But it still doesn't work. 但它仍然无效。 Here is the query after the change: 这是更改后的查询:

"select * from users where role = ? and ( id in (?, ?, ?, ?, ?, ?, ?)) or ( id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)) or ( username LIKE ? or keywords LIKE ? or profile_text LIKE ? or tagline LIKE ?) order by last_login desc" “select * from users where role =?and( id in(?,?,?,?,?,?,?))或( id in(?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?,?,?,?,?,?,?))或( username LIKE?或keywords LIKE?或profile_text LIKE?或tagline LIKE?)order by last_login desc“

That's because your query in SQL is this: 那是因为你在SQL中的查询是这样的:

WHERE keywords like '%...%' OR profile_text LIKE '%...%' 
OR tagline LIKE '%...%' AND role=2

The AND operator in SQL is like multiplication, it adds a parenthesis which means your query is really: SQL中的AND运算符就像乘法,它添加了一个括号,这意味着您的查询确实是:

WHERE keywords like '%...%' OR profile_text LIKE '%...%' 
OR (tagline LIKE '%...%' AND role=2)

So the filter role=2 is being applied to specific rows only (the ones where tagline LIKE '%...%' ). 因此,filter role=2仅应用于特定行tagline LIKE '%...%'的那些 )。 For rows where keywords like '%...%' OR profile_text LIKE '%...%' , role can be any value, which is not what you want. 对于keywords like '%...%' OR profile_text LIKE '%...%'行,角色可以是任何值,这不是您想要的。

What you need to do is apply the filtering WHERE on role directly on user . 您需要做的是直接在user上应用role过滤WHERE。 This also helps with efficiency undoubtably. 这无疑也有助于提高效率。

$users = User::where('role', 2)
  ->where(function($q) use($queryTags_userIDs,$queryImageTitles_userIDs,$query) {
      $q->whereIn('id', $queryTags_userIDs)
      ->orWhereIn('id', $queryImageTitles_userIDs)
      ->orWhere('username', 'LIKE', "%{$query}%")
      ->orWhere('keywords', 'LIKE', "%{$query}%")     
      ->orWhere('profile_text', 'LIKE', "%{$query}%")
      ->orWhere('tagline', 'LIKE', "%{$query}%");
   })->orderBy('last_login', 'desc')
   ->paginate(15);

Since it's not clear what result you want, I would suggest to view the query in SQL syntax. 由于不清楚你想要什么结果,我建议用SQL语法查看查询。 This can be done by replacing paginate(15) by toSql() and dd() the results. 这可以通过用toSql()dd()替换paginate(15)来完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM