就我而言,我有 channels 表,与 categories 表存在多对多关系。
我想获取其categories包含动态值的频道,就像对每个类别的标题进行
LIKE
查询一样。但我需要通过 where 子句检查 channel 的另一列。
这是一个通道结构:
[
{
"id": 87,
"username": "ch1",
"title": "ch title",
"type": "channel",
"members": 210424,
"location": "tabriz",
"created_at": "2017-05-09 01:39:44",
"updated_at": "2017-05-16 17:19:28",
}
]
为了得到我想要的东西,我运行这个查询:
$channels = Channel::orderBy('members', 'desc')
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->get();
上部查询返回我所有的channels,就像没有
whereHas
子句的查询一样,而当我单独使用'whereHas'时,它返回channels以及我想要的类别!
我使用了错误的语法吗?是否可以并排使用
where
和 whereHas
子句?
更新:
我需要对频道的标题或用户名进行
like
查询,所以我使用了orWhere
,但结果还是和以前一样!它将所有频道返回给我!就像再次没有 whereHas
的查询一样。
所以我用这个查询来做到这一点,
$channels = Channel::orderBy('members', 'desc')
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->orWhere([
['visible', 1],
['username', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->get();
起初我认为问题是 orderBy 子句,正如 @exprator 所说,但添加
orWhere
之后,我明白 orderBy
不是我的问题。
Channel::whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})->orderBy('members', 'desc')
在 order_by 之前使用 whereHas
->orWhere(function ($query) {
$query->where('visible', '=', 1)
->where('username', 'LIKE', '%' . $trend . '%')
->where('location', 'LIKE', '%' . $location . '%')
->where('members', '>', $members);
})
尝试在
->whereHas()
之后使用 ->where()
。您通常不需要复制任何东西。
$channels = Channel::where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->orWhere([
['visible', 1],
['username', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->orderBy('members', 'desc')
->get();
whereHas()
错误地与 where()
和 orWhere()
一起使用。在whereHas
之后,第二个和第三个条件必须组合在一个子例程中。目前您的查询将如下所示:
SELECT * FROM foo WHERE something_where_has 1 AND WHERE something 2 OR WHERE something 3 ..
但我认为你想要的是你的条件看起来像这样:
SELECT * FROM foo WHERE something_where_has 1 AND (WHERE something 2 OR WHERE something 3) ..
所以这可能对你有用:
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->where(function($q) {
$q->where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->orWhere([
['visible', 1],
['username', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]]);
})
我通过在
whereHas
之后复制 orWhere
子句解决了这个问题。
因此,为了获取我想要的类别中的频道,我使用了以下查询:
$channels = Channel::orderBy('members', 'desc')
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->where([
['visible', 1],
['title', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->orWhere([
['visible', 1],
['username', 'LIKE', '%' . $trend . '%'],
['location', 'LIKE', '%' . $location . '%'],
['members', '>', $members]])
->whereHas('categories', function ($query) use ($category) {
$query->where('title', 'LIKE', '%' . $category . '%');
})
->get();
也许这很奇怪,但效果很好!
你可以尝试这样的事情。我认为它会起作用。
$data = $request->all();
$stateZipCode = ZipCode::query()
->where('code', '=', $data['zipCode'])
->whereHas('states', function ($query) use ($data) {
return $query->where('name', $data['state']);
})
->with(['states' => function ($query) use ($data) {
return $query->where('name', $data['state']);
}])
->first();