按多个字段分组,然后生成总和
我有一个基于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
中的每个跳跃名称下的另一个级别,然后我可以使用它生成每跳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();
希望它能帮助:)
你可以重写整个招待作为原料的数组。这样一个招待对象的类型将是
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');
});
我给这个一展身手,但渴望与现有的查询来实现这一目标。 – James
@詹姆斯有时需要部分分解是必要的,如果它帮助,然后让我知道,我会尝试与您现有的查询。 – Sohel0415