我有一个基本的三个表,用户,来宾和帖子
我还有一个名为user_views的表: 存储帖子的唯一用户视图
post_id user_id
1 10002
2 10003
3 10011
另一个名为guest_views的表: 存储访客唯一的帖子视图
post_id guest_id
1 10002
2 10003
3 10011
在Post模型中,我有:
public function user_views()
{
return $this->hasMany('App\Models\PostUserView');
}
public function guest_views()
{
return $this->hasMany('App\Models\PostGuestView');
}
在下面的代码中,使用两个不同的键可以获得正确的结果。
$posts = Post::all()
->withCount('user_views')
->withCount('guest_views')
我想到将user_views和guest_views合并,然后按如下方式计算计数,但结果仅包括user_views的计数
public function views()
{
return $this->user_views()->unionAll($this->guest_views());
}
执行以下代码后
$posts = Post::all()
->withCount('views')
->withCount('user_views')
->withCount('guest_views')
我得到这个结果
"views_count": 5,
"user_views_count": 5,
"guest_views_count": 2,
示例示例的预期结果是:
"views_count": 7,
"user_views_count": 5,
"guest_views_count": 2,
我也尝试按照以下方式使用sql查询
public function views()
{
return DB::raw("(select * from post_views) union all (select * from post_guest_views)");
}
但是得到
"Call to undefined method Illuminate\Database\Query\Expression::getRelationExistenceCountQuery()"
因此,我想获取每个帖子的所有用户和来宾的总观看次数。
答案 0 :(得分:1)
在您的发布模型中
public function user_views()
{
return $this->hasMany('App\Models\PostUserView','user_id','id');
}
public function guest_views()
{
return $this->hasMany('App\Models\PostGuestView','user_id','id');
}
public function views()
{
return $this->user_views()->unionAll($this->guest_views());
}
现在您可以访问
$posts = Post::withCount(['user_views','guest_views','views'])->get()
注意
在 withCount()方法中指定的每个参数都变为 主对象的_count属性。所以在这种情况下,我们将拥有 $ posts-> guest_views_count,$ posts-> views_count和 $ posts-> user_views_count变量。
希望它对您有用。
答案 1 :(得分:0)
您可以使用join()
获得观看次数。下面是代码示例:-
$posts = Post::join('user_views as uv', function($q) {
$q->on('uv.post_id', '=', 'posts.id');
})
->join('guest_views as gv', function($q) {
$q->on('gv.post_id', '=', 'posts.id');
})
->selectRaw("posts.*, COUNT(uv.id) as user_views_count, COUNT(gv.id) guest_views_count, SUM(COUNT(uv.id) + COUNT(gv.id)) as views_count")
->groupBy("posts.id")
->get();
尝试一下。
答案 2 :(得分:0)
您可以按照以下方法使用reduce的收集方法:
$posts->reduce(function($carry,$item){
return $carry+$item->user_views_count;
},0);
有关更多信息,请查看reduce文档:https://laravel.com/docs/6.x/collections#method-reduce