You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中使用Eloquent查询构造器统计用户关联任务数

解决Laravel 8 Eloquent统计用户任务数的问题

方法一:使用Eloquent原生的withCount(最简洁)

首先确保User模型和UserTask模型定义正确的关联关系:

// app/Models/User.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function tasks()
    {
        return $this->hasMany(UserTask::class, 'user_id');
    }
}

然后直接通过withCount方法统计关联任务数,Laravel会自动处理LEFT JOIN和空值返回0的逻辑:

$users = User::select('id', 'name')
    ->withCount('tasks')
    ->get();

// 结果示例:
// $users[0]->id = 1, $users[0]->name = 'joe', $users[0]->tasks_count = 4
// $users[2]->id = 3, $users[2]->name = 'bob', $users[2]->tasks_count = 0

方法二:构造与原生SQL完全对应的查询构造器写法

如果需要严格匹配你提供的原生SQL,可以使用leftJoinSub方法关联子查询:

// 构造子查询:统计每个用户的任务数
$taskCountSubquery = DB::table('user_tasks')
    ->select('user_id as id', DB::raw('COUNT(*) as task_count'))
    ->groupBy('user_id');

// 主查询关联子查询,用COALESCE处理空值
$users = User::select([
        'users.id',
        'users.name',
        DB::raw('COALESCE(subquery.task_count, 0) as task_count')
    ])
    ->leftJoinSub($taskCountSubquery, 'subquery', function ($join) {
        $join->on('users.id', '=', 'subquery.id');
    })
    ->get();

方法三:使用DB::raw直接拼接子查询

如果你更习惯直接写原生子查询片段,也可以这样实现:

$users = User::select([
        'users.id',
        'users.name',
        DB::raw('COALESCE(subquery.task_count, 0) as task_count')
    ])
    ->leftJoin(
        DB::raw('(SELECT user_id as id, COUNT(*) as task_count FROM user_tasks GROUP BY user_id) as subquery'),
        'users.id',
        '=',
        'subquery.id'
    )
    ->get();

对你初始尝试的修正

你之前的代码错误在于子查询部分重复查询了users表,而应该针对user_tasks做分组统计,同时没有正确设置关联条件。上面的方法二和方法三都解决了这个问题。

内容的提问来源于stack exchange,提问作者Darren Gates

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 17:50:55