[英]Group by multiple fields and then generate a sum
我有一個基於Laravel 5.2的配方構建應用程序。
用戶可以在他們的食譜中添加成分,有時您可能會根據您使用的成分將相同的成分添加兩次。
我正在構建允許用戶為其配方生成購物清單的功能,這應該為他們生成PDF購物清單。
到目前為止,我已經生成了成分列表,但是我還不太了解如何進行分組和求和。
典型的列表如下所示:
[
{
"id":97724,
"name":"Citra Pellets",
"amount":6.5,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97725,
"name":"Simcoe Pellets",
"amount":6.5,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97726,
"name":"Citra Pellets",
"amount":6.5,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97727,
"name":"Simcoe Pellets",
"amount":6.5,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97729,
"name":"Mosaic Pellets",
"amount":79.9999,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97730,
"name":"Simcoe Pellets",
"amount":60,
"hop_type_id":"Combined",
"recipe_id":23453
}
]
目前,在我看來,我只是有一個foreach
循環遍歷這些,以吐出結果; 出來像這樣:
+--------+----------------+------------+
| Amount | Name | Usage Type |
+--------+----------------+------------+
| 6.5 | Citra Pellets | Pellet |
| 6.5 | Simcoe Pellets | Pellet |
| 6.5 | Citra Pellets | Pellet |
| 6.5 | Simcoe Pellets | Pellet |
| 79.99 | Mosaic Pellets | Pellet |
| 60 | Simcoe Pellets | Combined |
+--------+----------------+------------+
我要做的是按成分的名稱和用途類型將其分組,然后獲取金額的總和。 所以輸出是這樣的:
+--------+----------------+------------+
| Amount | Name | Usage Type |
+--------+----------------+------------+
| 13 | Citra Pellets | Pellet |
| 13 | Simcoe Pellets | Pellet |
| 79.99 | Mosaic Pellets | Pellet |
| 60 | Simcoe Pellets | Combined |
+--------+----------------+------------+
到目前為止,我的嘗試包括App\\Models\\Recipe::find(23453)->hops->groupBy('name')
-這為我提供了以下內容:
{
"Citra Pellets":[
{
"id":97724,
"name":"Citra Pellets",
"amount":6.5,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97726,
"name":"Citra Pellets",
"amount":6.5,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97728,
"name":"Citra Pellets",
"amount":94.9999,
"hop_type_id":"Pellet",
"recipe_id":23453
}
],
"Simcoe Pellets":[
{
"id":97725,
"name":"Simcoe Pellets",
"amount":6.5,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97727,
"name":"Simcoe Pellets",
"amount":6.5,
"hop_type_id":"Pellet",
"recipe_id":23453
},
{
"id":97730,
"name":"Simcoe Pellets",
"amount":60,
"hop_type_id":"Combined,
"recipe_id":23453
}
],
"Mosaic Pellets":[
{
"id":97729,
"name":"Mosaic Pellets",
"amount":79.9999,
"hop_type_id":"Pellet",
"recipe_id":23453
}
]
}
然后,這允許我遍歷每個對象,然后->sum('amount')
以獲得總和值。 但是,它沒有考慮到重要的hop_type_id
。
我也嘗試鏈接->groupBy('hop_type_id')
,以及使用->each(function ($item, $key))
但還沒有解決。
看起來像集合上的初始groupBy()
生成了一個鍵對象,這些鍵在其下面有一個值數組。
理想情況下,我hop_type_id
為每個hop_type_id
的每個躍點名稱添加另一個級別,然后可以使用該hop_type_id
生成每個躍點name
和hop_type_id
。
我該如何實現?
我想您正在尋找這個-
\App\Ingredient::where('recipe_id','=',23453)->selectRaw('sum(amount) as amount, name, hop_type_id')->groupBy('name')->groupby('hop_type_id')->get();
希望能幫助到你 :)
您可以將整個容器重寫為多種成分。 這樣,Recept對象的類型將是
Ingredient[]
每個成分將具有以下私有字段以及相應的公共獲取者
$id, (string) $name, (int) $amount, $hop_type_id, $recipe_id
然后,您可以生成如下的購物清單
$shoppingList = [];
foreach($recept as $ingredient) {
$shoppingList[$ingredient->getName()] += $ingredient->getAmount();
}
因此,我使用現有集合解決了該問題,而不必使用原始查詢或修改數據庫架構。
您可以使用groupBy()
,然后使用transform()
實現此目的:
$recipe = App\Models\Recipe::find(23453);
$hops = $recipe->hops->groupBy('name')
->transform(function ($hop, $key) {
return $hop->groupBy('hop_usage_type');
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.