如何计算所有Share类的totalIssued()方法结果总和?
这里有几种实用的方案,你可以根据数据量和业务场景来选择:
1. 利用Eloquent集合求和(适合小数据量或已有Share集合的场景)
如果你的数据量不大,或者已经获取了所有Share的集合,可以直接借助集合的sum方法来计算:
// 方式1:显式调用totalIssued方法 $allShares = Share::with('grants')->get(); // 预加载grants避免N+1查询 $totalAllIssued = $allShares->sum(function ($share) { return $share->totalIssued(); }); // 方式2:更简洁的语法,Eloquent会自动调用属性/方法 $totalAllIssued = Share::with('grants')->get()->sum('totalIssued');
⚠️ 注意:一定要加上with('grants')预加载关联,不然每个Share实例都会单独查询一次grants表,触发N+1查询问题,数据量大时性能会急剧下降。
2. 直接通过数据库聚合查询(性能最优,推荐)
如果数据量较大,直接在数据库层面完成求和是最高效的方式,不需要加载任何模型实例,只需要一次SQL查询:
$totalAllIssued = Share::join('grants', 'shares.id', '=', 'grants.share_id') ->sum('grants.shares_amount');
请根据你的实际表结构调整字段名:比如shares.id是Share表的主键,grants.share_id是Grant表关联Share的外键,如果你的字段名不同,对应修改即可。
如果需要包含软删除的Grant记录,可以加上withTrashed():
$totalAllIssued = Share::join('grants', 'shares.id', '=', 'grants.share_id') ->withTrashed() // 假设Grant模型开启了软删除 ->sum('grants.shares_amount');
3. 用Eloquent的withSum关联统计
Laravel提供了withSum方法,可以一次性获取每个Share对应的grants的shares_amount总和,然后再对这些值求和:
// 先获取每个Share的总和,存储在grants_sum_shares_amount字段中 $sharesWithTotal = Share::withSum('grants', 'shares_amount')->get(); // 对所有Share的总和再求和 $totalAllIssued = $sharesWithTotal->sum('grants_sum_shares_amount');
这种方式的好处是既避免了N+1问题,又能同时拿到每个Share的单独总和和全局总和,适合需要同时展示两种数据的场景。
内容的提问来源于stack exchange,提问作者Philipp Kishkovarov
相关产品推荐
相关产品推荐

