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

标签 php mysql sql laravel

我有一个基于某些参数获取用户的查询。

$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);

现在,这一切都很好。

除了这部分:

->where('role', 2)

它不是获取角色为 2 的用户,而是获取每个角色的用户。

但是,如果我去掉一些 orWheres,它就会起作用。

如果我摆脱这 3 个 orWheres:

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

然后它开始只获取角色 2 的用户。事实上,无论出于何种原因,这 3 个特定的 orWheres 都会导致问题

如果我将查询减少到只有

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

它仍然从角色 2 之外获取用户。

但是,如果将其切换为:

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

然后突然间它只从角色 2 中获取用户。

为什么会这样?我觉得我错过了一些非常明显的东西,因为这毫无意义。

编辑

为了响应 Bassem El Hachem,我将 role = 2 放在查询的开头。但它仍然不起作用。这是更改后的查询:

"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"

最佳答案

那是因为你在 SQL 中的查询是这样的:

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

SQL 中的 AND 运算符就像乘法,它添加了一个括号,这意味着您的查询实际上是:

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

因此过滤器 role=2 被应用于仅特定行(tagline LIKE '%...%' ).对于 keywords like '%...%' OR profile_text LIKE '%...%' 的行,role 可以是任何值,这不是您想要的。

您需要做的是直接在 user 上对 role 应用 WHERE 过滤。这无疑也有助于提高效率。

$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);

由于不清楚您想要什么结果,我建议以 SQL 语法查看查询。这可以通过将 paginate(15) 替换为 toSql()dd() 结果来完成。

关于php - Laravel where 子句在一系列 orwhere 之后不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46437453/

相关文章:

sql - 加入和分组时避免无用的子查询或聚合

javascript - 使用 laravel 和 ajax 部分页面重新加载

php - 页面加载时发出声音

php - 在 Codeigniter 中使用 UNION 并出现错误?

mysql - 查找雇员表 MySQL 的最大和第二最大工资,不按数字计算

sql - 对多行使用 SELECT INTO

javascript - Symfony Controller 返回的变量始终未定义

php - php中的随机数生成器

php - 连接表中缺少数据时出现 SQL 连接错误

sql - 关于 MySQL 中有效表使用的问题