我有一个根据某些参数获取用户的查询。
$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的位置,它会获取每个角色的用户。
然而,如果我摆脱某些或者某些方面它会起作用。
如果我摆脱这些3或者球:
->orWhere('keywords', 'LIKE', "%{$query}%")
->orWhere('profile_text', 'LIKE', "%{$query}%")
->orWhere('tagline', 'LIKE', "%{$query}%")
然后它开始仅使用角色2获取用户。事实上,无论出于何种原因,这3个特定或者范围都会导致问题
如果我将查询简化为
$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。但它仍然无法奏效。这是更改后的查询:
"从
排序users
中选择*role
=?和(id
in(?,?,?,?,?, ?,?))或(id
in(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, ?,?,?,?))或(username
LIKE?或keywords
LIKE?或profile_text
喜欢?或tagline
LIKE?)按last_login
desc"
答案 0 :(得分:1)
那是因为您在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
上的过滤WHERE直接应用于user
。这无疑也有助于提高效率。
$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()
结果来完成。