Laravel的withCount方法通过单次查询中的COUNT聚合避免N+1问题,高效统计关联模型数量;基本用法如User::withCount('posts')获取用户及其文章数,生成子查询SQL并添加xxx_count字段;支持统计多个关联如posts、comments,并可为字段自定义别名;可通过闭包添加where条件实现条件计数,如仅统计已发布或激活状态的文章;可与with共用以同时获取关联数据和数量,但若无需关联数据则应避免使用with以防内存浪费;适用于列表页展示评论数、订单数等需计数场景,提升性能且用法灵活。

Laravel 的 withCount 方法是高效统计关联模型数量的推荐方式,它通过在主查询中使用 SQL 的 COUNT 聚合函数,避免了 N+1 查询问题,显著提升性能。相比循环中调用关系再计数,withCount 只会额外增加一个子查询或左连接,效率更高。
基本用法:统计一对一或一对多关联数量
假设你有一个 User 模型,每个用户有多个 Post,你想获取所有用户并附带他们的文章数量:
$users = User::withCount('posts')->get();
foreach ($users as $user) {
echo $user->name . ' 有 ' . $user->posts_count . ' 篇文章';
}
这会在底层生成类似以下的 SQL:
SELECT users.*, (SELECT COUNT(*) FROM posts WHERE posts.user_id = users.id) AS posts_count FROM users;
统计多个关联或自定义字段名
你可以同时统计多个关联,并为结果字段指定别名:
$users = User::withCount([
'posts',
'comments',
'posts as published_posts_count' => function ($query) {
$query->where('status', 'published');
}
])->get();
这时你会得到:posts_count、comments_count 和自定义条件的 published_posts_count。
结合约束条件进行条件计数
如果只想统计满足特定条件的关联记录,可以在闭包中添加 where 条件:
$users = User::withCount([
'posts as active_posts_count' => function ($query) {
$query->where('is_active', 1);
}
])->get();
这样只统计激活状态的文章数量,且字段名为 active_posts_count。
与 with 共存但注意性能取舍
可以同时使用 with 和 withCount,比如既要加载文章列表,又要知道总数:
$users = User::with('posts')->withCount('posts')->get();
但要注意:如果只是需要数量,不要盲目加上 with,否则会拉取全部关联数据,造成内存浪费。
withCount 能有效减少数据库查询次数,尤其适合列表页展示“评论数”“订单数”等场景,不复杂但容易忽略细节。










