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

如何在Laravel Eloquent中用withCount合并两个关联表的统计数?

用Eloquent withCount直接合并统计friends_reactions与friends_activities的总数

你可以通过以下几种方式实现预加载时直接获取合并后的engagements_count:

方法一:在withCount中使用子查询合并统计

直接在withCount的闭包里通过unionAll合并两个表的关联数据,再统计总数:

use Illuminate\Support\Facades\DB;

$friends = Friend::withCount([
    // 保留原有单独统计(可选)
    'reactions',
    'activities',
    // 合并统计engagements
    'engagements' => function ($query) {
        $query->select(DB::raw('COUNT(*)'))
              ->fromSub(function ($sub) {
                  // 合并两个表的friend_id
                  $sub->select('friend_id')
                      ->from('friends_reactions')
                      ->unionAll(
                          DB::table('friends_activities')->select('friend_id')
                      );
              }, 'combined_engagements')
              ->whereColumn('combined_engagements.friend_id', 'friends.id');
    }
])->get();

查询完成后,每个Friend实例会自动带上engagements_count字段,即两个表的记录总数之和。

方法二:自定义关联后用withCount统计

先在Friend.php模型中定义一个合并了reactions和activities的关联:

use Illuminate\Support\Facades\DB;

public function engagements()
{
    return $this->fromQuery(
        DB::table('friends_reactions')
            ->select('friend_id')
            ->unionAll(DB::table('friends_activities')->select('friend_id'))
            ->whereColumn('friend_id', 'friends.id')
    );
}

之后直接通过withCount统计这个关联即可:

$friends = Friend::withCount('engagements')->get();

拓展:添加过滤条件

如果需要针对特定type的记录统计,可以在子查询中添加where条件:

public function engagements()
{
    return $this->fromQuery(
        DB::table('friends_reactions')
            ->select('friend_id')
            ->where('type', 'like') // 只统计点赞类的reactions
            ->unionAll(
                DB::table('friends_activities')
                    ->select('friend_id')
                    ->where('type', 'comment') // 只统计评论类的activities
            )
            ->whereColumn('friend_id', 'friends.id')
    );
}

方法三:基于已有count字段相加(简洁版)

如果不需要从数据库层面合并统计,也可以直接利用已有的reactions_count和activities_count,通过selectRaw计算总和:

$friends = Friend::withCount(['reactions', 'activities'])
    ->selectRaw('friends.*, (reactions_count + activities_count) as engagements_count')
    ->get();

这个方式代码更简洁,适合不需要复杂过滤的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:52:44