Reputation: 1421
I am trying to sum a column while grouping by data within the table as well as a related table.
Order Table
Order Items Table
Relationships
Order item belongs to Order
public function order() : BelongsTo
{
return $this->belongsTo(Order::class);
}
Query
I am looking for a result of:
The following gets a collection with the correct groups:
$items = OrderItem::with(['order'])
->get()
->groupBy(['fulfilment_location_id', 'product_id']);
I can then walk through this array to get the result I am looking for as follows:
$result = [];
foreach($items as $location_id => $products_collection){
foreach($products_collection as $product_id => $order_items_collection){
$sum = $order_items_collection->sum(function(OrderItem $oi){
return $oi->qty;
});
isset($result[$location_id][$product_id]) ?
$result[$location_id][$product_id] += $sum :
$result[$location_id][$product_id] = $sum;
}
}
... however this seems very long winded. I could get the result far easier by just duplicating the location_id column from the orders table to the order_items table, but this does not feel very nice. I hoped there would be a simpler way that uses eloquent (opposed to writing a raw query).
Upvotes: 1
Views: 656
Reputation: 7420
Something along the lines of this:
$items = OrderItem::select(DB::raw('sum(order_items.qty) as sumqty, o.location_id as lcoation, order_items.product_id as product_id'))
->leftJoin('orders as o', 'o.id', 'order_items.order_id')
->groupBy(['product_id', 'lcoation']);
Should give you:
sumqty | location | product_id
---------------------------------
12 3 12 // example data
Upvotes: 1