Search code examples
phpsqlmysqlisumgrouping

Group items from database table and calculate total price for each item given a number of items


I have a multidimensional array. I need to group and sum the values of the array that have the same index name. Here is what I have:

Array
(
[Garlic Potatoes] => 625
[Rice] => 1025
[Chicken Shawarma] => 1675
[Pita Bread Sm] => 6
[Pita Bread Large] => 14
[Beef Shawarma] => 1755
[Can of Pop] => 2
[Brioch Bun] => 2
[Chicekn Shawarama] => 135
)

How can I end up with one instance of Chicken Shawarma and qty = 1405 ? Do I need to use a foreach?

$sql = "SELECT menu_id, SUM(quantity) AS qty FROM daily_consumption_details WHERE consumption_id = $id GROUP BY menu_id";
$res = $conn->query($sql);

$ingredients = [];

while($menu = $res->fetch_object())
{

    $sql_ing = "SELECT item_name, quantity FROM menu_details WHERE menu_id = $menu->menu_id ";
    $rs = $conn->query($sql_ing);
    while($items = $rs->fetch_object())
    {
        $qty = $menu->qty * $items->quantity;
    
        if ( array_key_exists(trim($items->item_name), $ingredients) ) 
            $ingredients[trim($items->item_name)] = $qty + $ingredients[trim($items->item_name)];
        else 
            $ingredients[trim($items->item_name)] = $qty; 

    }
}

Solution

  • If you make the item_name the key of the new ingredients array you can easily check if you already created an entry for this ingredient

    while($menu = $res->fetch_object())
    {
    
        $sql_ing = "SELECT item_name, quantity FROM menu_details WHERE menu_id = $menu->menu_id ";
        $rs = $conn->query($sql_ing);
        while($items = $rs->fetch_object())
        {
            $qty = $menu->qty * $items->quantity;
            $item = trim($items->item_name);
            if ( array_key_exists($item, $ingredients) ) {
                $ingredients[$items] += $qty;
            } else {
                $ingredients[$items] = $qty; 
            }
        }
    }
    

    The resulting $ingredients array will look about the same except the key will be the item name and not a numeric, 0,1,2, etc