2017-11-25 262 views
0

我有一個基於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中的每個跳躍名稱下的另一個級別,然後我可以使用它生成每跳namehop_type_id的總和。

我該如何做到這一點?

回答

0

我認爲你正在尋找這個 -

\App\Ingredient::where('recipe_id','=',23453)->selectRaw('sum(amount) as amount, name, hop_type_id')->groupBy('name')->groupby('hop_type_id')->get(); 

希望它能幫助:)

+0

我給這個一展身手,但渴望與現有的查詢來實現這一目標。 – James

+0

@詹姆斯有時需要部分分解是必要的,如果它幫助,然後讓我知道,我會嘗試與您現有的查詢。 – Sohel0415

0

你可以重寫整個招待作爲原料的數組。這樣一個招待對象的類型將是

 Ingredient[] 

每種成分將具有以下私有字段與相應的公共干將

  $id, (string) $name, (int) $amount, $hop_type_id, $recipe_id 

然後,您可以生成一個購物清單像如下

$shoppingList = []; 
foreach($recept as $ingredient) { 
    $shoppingList[$ingredient->getName()] += $ingredient->getAmount(); 
} 
+0

這是一個現有應用程序的新功能,不可悲的重寫。 – James

+0

如果在foreach循環的結果中,只是檢查某個成分是否已經添加到列表中,該怎麼辦?如果是,則只需添加新數量,而在另一種情況下,則向列表中添加新元素。如果你發佈你的foreach循環,我可以更具體一些。 – Annibale

0

所以我使用現有的集合來解決它,而不必使用原始查詢或修改數據庫模式。

您可以使用groupBy()然後transform()來實現這一目標:

$recipe = App\Models\Recipe::find(23453); 

$hops = $recipe->hops->groupBy('name') 
     ->transform(function ($hop, $key) { 
      return $hop->groupBy('hop_usage_type'); 
     }); 
相關問題