Reputation: 3189
I have Invoice_Detail
model which handles all products and it's quantities, this model table invoice_details
has item_id
and qty
columns.
The Invoice_Detail
has a relation to Items
model which holds all item's data there in its items
table, which has item_id
, name
, category_id
.
The Item
model also has a relation to Category
model which has all categories data in its categories
table.
Question: I want to select top five categories from Invoice_Detail
, how?
Here's what I did:
$topCategories = InvoiceDetail::selectRaw('SUM(qty) as qty')
->with(['item.category' => function($query){
$query->groupBy('id');
}])
->orderBy('qty', 'DESC')
->take(5)->get();
But didn't work !!
[{"qty":"11043","item":null}]
Upvotes: 4
Views: 12150
Reputation: 109
Category::select('categories.*',\DB::raw('sum("invoice_details"."qty") as "qty"'))
->leftJoin('items', 'items.category_id', '=', 'categories.id')
->leftJoin('invoice_details', 'invoice_details.item_id', '=', 'items.id')
->groupBy('categories.id')
->orderBy('qty','DESC')
->limit(5)
->get();
This will return you collection of top categories. Tested on laravel 5.5 and PostgreSQL.
UPD: To solve this without joins you can add to Categories model this:
public function invoiceDetails()
{
return $this->hasManyThrough(Invoice_Detail::class, Item::class);
}
And to select top 5 categories:
$top = Category::select()->with('invoiceDetails')
->get()->sortByDesc(function($item){
$item->invoiceDetails->sum('qty');
})->top(5);
But first solution with joins will work faster.
Upvotes: 1