我在users
和activities
之间建立了一对一的关系,这样每个用户都有last_activity_id
映射到activities
中的特定行。< / p>
我需要能够根据上一个活动中的列值过滤用户列表。为了能够执行其他事情,例如分页,这必须在查询本身中完成,因此我无法获取结果,然后在事后应用过滤器。因此,我使用select
和leftJoin
将相关列直接添加到我的结果集中:
$query = User::select(
'users.*',
'activities.description as last_activity_description')
->leftJoin('activities', 'activities.id', '=', 'users.last_activity_id')
->having('last_activity_description', 'like', "%blanchin%");
这似乎工作正常,我可以调用$query->get()
来获取过滤结果集。它生成一个如下所示的查询:
select `users`.*,
`activities`.`description` as `last_activity_description`
from `users`
left join `activities` on `activities`.`id` = `users`.`last_activity_id`
having `last_activity_description` like '%blanchin%'
但是,如果我尝试通过调用$query->count()
在此结果集上获取 count ,则Laravel会生成此(失败)查询:
select count(*) as aggregate
from `users`
left join `activities` on `activities`.`id` = `users`.`last_activity_id`
having `last_activity_description` like '%blanchin%'
似乎调用count()
已删除我原来的select
子句并将其替换为select count(*) as aggregate
,这意味着我的having
子句失败,因为last_activity_description
别名已不再定义。
我该如何解决这个问题?
答案 0 :(得分:1)
似乎解决方法是不在我的约束中使用别名,而只是使用实际的表和列名称。这很好用:
$query = User::select(
'users.*',
'activities.description as last_activity_description')
->leftJoin('activities', 'activities.id', '=', 'users.last_activity_id')
->where('activities.description', 'like', "%blanchin%")
->count();
另请注意,having
子句需要更改为where
子句。
答案 1 :(得分:0)
为什么不使用关系约束和分页?
User::whereHas('activities', function($query) use ($description) {
return $query->where('description', 'LIKE', "%$description%");
})->paginate($results);
如果您想要返回活动描述:
User::whereHas('activities', function($query) use ($description) {
return $query->where('description', 'LIKE', "%$description%");
})->with(['activities' => function($query) use ($description) {
return $query->select('id', 'description as last_activity_description')
->where('description', 'LIKE', "%$description%");
}])->paginate($results);
<强>更新强>
以上内容适用于您的用户模型定义的activities()
关系:
public function activities()
{
return $this->belongsTo(Activity::class, 'last_activity_id');
}