如何将统计用户回复数的MySQL查询整合到Laravel Eloquent查询中?
如何在Laravel Eloquent中整合回复总数统计查询
嘿,我来帮你搞定这个问题!你现在有一个获取帖子回复的Eloquent查询,还想给每条回复加上对应用户的总回复数,下面分几种方式来实现:
方式一:给现有查询添加用户回复统计字段
你原来的Eloquent查询是这样的:
$data->replies = Reply::where('thread_id', '=', $thread) ->with('user') ->orderBy('created_at', 'ASC') ->paginate(20);
要给每条回复加上该用户的总回复数,我们可以用addSelect结合子查询来实现,修改后的代码如下:
$data->replies = Reply::where('thread_id', $thread) ->with('user') // 添加用户总回复数字段 ->addSelect([ 'cnt' => Reply::selectRaw('count(*)') ->whereColumn('user_id', 'replies.user_id') ]) ->orderBy('created_at', 'ASC') ->paginate(20);
这里的核心是whereColumn,它能让子查询关联当前主查询的user_id,从而统计出该用户所有回复的总数,最终每条回复对象里会多出一个cnt属性,就是你要的总数。
方式二:用Eloquent重写你的原生MySQL查询
你的原生SQL语句是:
SELECT user_id, text, (SELECT count(*) from replies AS t2 WHERE t1.user_id=t2.user_id) AS cnt FROM replies AS t1 WHERE thread_id = 910 ORDER BY `t1`.`user_id` ASC
对应的Eloquent写法可以完美还原这个逻辑,代码如下:
$replies = Reply::from('replies as t1') ->select('t1.user_id', 't1.text') ->addSelect([ 'cnt' => Reply::selectRaw('count(*)') ->from('replies as t2') ->whereColumn('t2.user_id', 't1.user_id') ]) ->where('t1.thread_id', 910) ->orderBy('t1.user_id', 'ASC') ->get();
如果需要分页,直接把最后的get()换成paginate(20)就可以了。
方式三:利用Eloquent关联关系更优雅实现
其实还有一种更符合Laravel思想的方式——通过模型关联来统计。首先在User模型里定义回复关联:
// app/Models/User.php public function replies() { return $this->hasMany(Reply::class); }
然后在查询回复的时候,通过withCount直接获取用户的总回复数,代码如下:
$data->replies = Reply::where('thread_id', $thread) ->with(['user' => function($query) { // 给用户模型添加replies_count字段 $query->withCount('replies'); }]) ->orderBy('created_at', 'ASC') ->paginate(20);
这种方式下,每条回复的user属性里会多出一个replies_count字段,就是该用户的总回复数,代码更简洁,也更符合Eloquent的关联设计。
内容的提问来源于stack exchange,提问作者Linas Lg
相关产品推荐
相关产品推荐

