laravel 9 中 withcount() 支持带条件关联计数,通过闭包传入 where、wherehas 等约束,并可自定义别名;字段名需匹配关联模型表,避免与默认 _count 后缀混淆。

在 Laravel 9 中,withCount() 可以方便地统计关联模型的数量,同时支持添加条件筛选,实现「带条件的关联计数」。关键在于传入闭包来定义查询约束。
基础用法:统计关联总数
比如一个 User 模型关联了多个 Post,要查每个用户发布的文章数:
$users = User::withCount('posts')->get();
// 结果中每个 $user->posts_count 可直接访问
带条件统计:只统计满足条件的关联记录
在 withCount() 中传入闭包,对关联查询添加 where、whereIn、whereHas 等约束:
- 统计「已发布」的文章数量(假设
Post表有status字段):
User::withCount(['posts' => function ($query) {
$query->where('status', 'published');
}])->get();
// 得到 $user->posts_count(仅含 status = 'published' 的数量)
- 统计「最近 30 天内创建」的文章数:
User::withCount(['posts' => function ($query) {
$query->where('created_at', '>=', now()->subDays(30));
}])->get();
- 结合多条件(如状态 + 分类):
User::withCount(['posts' => function ($query) {
$query->where('status', 'published')
->where('category_id', 1);
}])->get();
别名自定义:避免字段名冲突
当需要多个带条件的统计,或想让字段名更语义化,可用数组键指定别名:
User::withCount([
'posts', // 默认 → posts_count
'posts as published_posts_count' => function ($query) {
$query->where('status', 'published');
},
'posts as draft_posts_count' => function ($query) {
$query->where('status', 'draft');
}
])->get();
// 结果包含:$user->posts_count, $user->published_posts_count, $user->draft_posts_count
嵌套关联与复杂条件(如 whereHas)
若需基于关联模型的深层关系过滤(例如统计「有评论的已发布文章」),可在闭包中使用 whereHas:
User::withCount(['posts' => function ($query) {
$query->where('status', 'published')
->whereHas('comments'); // 要求该 post 至少有一条评论
}])->get();
注意:whereHas 在 withCount 的闭包中是完全支持的,Laravel 会将其正确编译为子查询或 JOIN 条件。
不复杂但容易忽略的是:闭包里的查询对象是关联表的查询构建器,字段名需对应关联模型的数据表,而不是主模型;别名命名建议清晰,避免和默认 _count 后缀混淆。











