我有两个模型,Plan
和Transactions
。每个Plan
都可以有多个Transactions
。我想获得与所有计划相关的所有交易的总金额。现在我这样做:
$plans = $this->plan->with('transactions')->get();
$total = [];
foreach($plans as $plan)
{
foreach($plan->transactions as $transaction)
{
$total[] = $transaction->amount;
}
}
dd(array_sum($total)); // Works, I get the total amount of all transactions that are related to a Plan.
但我想摆脱foreach循环并改用filter
和/或map
。我尝试过以下方法:
$test = $plans->filter(function ($plan) {
return $plan->has('transactions');
})->map(function ($plan) {
return $plan->transactions;
})->map(function ($transaction) {
return $transaction; // Not sure what to do here, $transaction->amount doesn't work
});
我有点陷入最后一点,我最终得到了一系列收藏品。关于如何实现这一点的任何想法,至少不使用foreach循环?也许在查询本身?
所以我拥有的是Plans
,而Plan
每个Transactions
都有Transaction
。每个amount
都有一个Transaction
字段,我在其中存储每个{{1}}的金额。我希望获得与计划相关的所有交易的总金额。所以,transactions.amount的总和。
答案 0 :(得分:1)
由于您有计划ID,因此可以使用sum()
方法:
$this->transaction->where('plan_id', $planId)->sum('amount');
要计算所有交易的金额,请移除where()
部分。
要计算多个计划的金额,请使用whereIn()
intsead where()
。
答案 1 :(得分:1)
假设您已有计划,该计划上的交易属性将是一个集合,因此您可以使用sum()
方法:
$total = $plan->transactions->sum('amount');
因为它只是一个特定的计划,所以你是否急于加载并不重要。但是如果它还没有加载,你可以通过数据库来代替它:
$total = $plan->transactions()->sum('amount');
如果您有一系列计划,请使用reduce()
:
$total = $plans->reduce(function ($carry, $plan) {
return $carry + $plan->transactions->sum('amount');
}, 0);
在这种情况下,您确实希望加载事务以减少查询次数。 (否则,请通过数据库参考上面的内容。)
如果您来自查询,可以使用联接或双查询 - 后者通常更简单:
$ids = Plan::where('condition')->pluck('id')->all();
$total = Transaction::whereIn('plan_id', $ids)->sum('amount');
当然,如果您只想要总量,那么根本不需要完成计划。 :)
$total = Transaction::sum('amount');