我有两个模型。 Expense
和Method
。我想为每个sum
抓住所有expenses
中的method type
。我有四种类型:
- bank
- credit-card
- wallet
- savings
每个费用都属于一个方法,并且每个方法都有许多费用。因此,这是一对多关系。因此,method_id
会存储在每个费用中。
例如,以下查询用于获取具有类型为bank
的方法的所有费用的总和:
$type = 'bank';
$expenses = auth()->user()->expenses()->with('method')->whereHas('method', function ($query) use ($type) {
$query->where('type', $type);
})->sum('amount');
但是事实是,如果我想获取每种方法类型的所有费用的总计,那么我将不得不运行太多查询。我希望仅获取所有费用,然后对它们进行过滤以获取每种方法类型的所有费用之和。
以下示例不起作用:
$expenses = auth()->user()->expenses()->with('method')->get();
$bank_balance = $expenses->filter(function ($expense)
{
$expense->whereHas('method', function ($query) {
$query->where('type', 'bank');
})->get(); // with or without ->get()
});
有什么想法可以通过不使用太多查询来获得我想要的东西吗?
编辑:
我没有接受选择的答案,因为它最终没有给我我所需要的。我需要能够执行以下操作:
{{ $bank_balance }}
这意味着,用xyz的答案,我将无法做到这一点,因为我无法区分它们。我只能根据method_id获得结果,但是我需要能够通过方法名称来区分它们。
DigitalDrifter的答案几乎可以解决问题,但这给了我:
Collection {#800 ▼
#items: array:3 [▼
"bank" => Collection {#797 ▼
#items: array:30 [▼
0 => array:2 [▼
"type" => "bank"
"amount" => 1536
]
1 => array:2 [▶]
2 => array:2 [▶]
3 => array:2 [▶]
4 => array:2 [▶]
5 => array:2 [▶]
]
}
"credit-card" => Collection {#798 ▶}
"wallet" => Collection {#799 ▶}
]
}
我基本上需要这样简单的东西:
“银行” =>“这里所有使用'银行'方法的费用的总和” “ credit-card” =>“这里所有使用'credit-card'方法的费用的总和”
以此类推。
我认为->groupBy('type')->each->sum('amount')
可以解决问题,但不能完全解决。如上面的集合示例所示,它会按类型分组,但不会给出每种类型的总和。
答案 0 :(得分:2)
您可以按方法ID分组,然后将结果加到一条select语句中。
以下未经测试。
$expenses = auth()->user()
->expenses()
->select(DB::raw('SUM(amount) as total'), 'other_select_fields', ...)
->with('method')
->groupBy('method_id')
->get();
答案 1 :(得分:1)
您可以使用可用的收集方法进行此操作:
$expenses = auth()->user()->expenses()->with('method')->get();
$groupedSums = $expenses->map(function ($expense) {
return [
'type' => $expense['method']['type'],
'amount' => $expense['method']['amount']
];
})->groupBy('type')->each->sum('amount');