我有一个基于某些参数获取用户的查询。
$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
whererole
= ? and (id
in (?, ?, ?, ?, ?, ?, ?)) or (id
in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)) or (username
LIKE ? orkeywords
LIKE ? orprofile_text
LIKE ? ortagline
LIKE ?) order bylast_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/