groupBy withCount 闭包(Laravel 5.3.26)
Posted
技术标签:
【中文标题】groupBy withCount 闭包(Laravel 5.3.26)【英文标题】:groupBy within withCount closure (Laravel 5.3.26) 【发布时间】:2017-05-07 06:33:42 【问题描述】:在 Laravel 5.3.26 中,是否可以根据该关系的列对 withCount
的结果进行分组?例如如下:
$brands = \App\Models\Brand::withCount([ 'products' => function ($query)
$query->groupBy('extra_attribute');
])
->get();
这段特定的代码返回一个空集合。
也许我只是没有在文档中找到正确的位置,或者没有正确使用谷歌搜索,但我找不到关于这个特定场景的任何信息。
有人能给我指出正确的方向吗?
非常感谢!
编辑:目前我似乎已经解决了这个问题:
$brands = \App\Models\Brand::with([ 'products' => function ($query)
$query->select('brand_id', 'extra_attribute')
->selectRaw('COUNT(*) AS products_count')
->groupBy('extra_attribute');
]);
并能够通过$brand->products->sum('products_count')
之类的方式获取总数。
感觉非常脏,而且可能是。这真的是唯一的方法吗?
【问题讨论】:
【参考方案1】:当然,你也可以像在 with() 中一样为 withCount() 传递一个闭包,例如,如下所示,在 product_id 1
上的访问计数为 user_id 1
User::where('id', 1)
->withCount(['visits'=> function($q) use ($product_id)
$q->where('product_id', $product_id);
])
【讨论】:
【参考方案2】:groupBy()
不应该在withCount()
中使用,因为withCount()
将急切加载products
集合中所有项目的计数,每个Brand
在返回的由Brand
分组收藏。这相当于单个Brand
上的$brand->products->count()
。
在您的 2 个示例之间,如果您不在其他地方使用此数据,groupBy()
是不必要的。如果是,最好按以下方式访问集合中的总数:
//Controller
$brands = \App\Models\Brand::with('products')->get();
//View
@foreach($brands as $brand)
<div>TOTAL PRODUCTS: $brand->products->count() </div>
@foreach($brand->products->groupBy('extra_attribute') as $attribute => $products)
<div>TOTAL $attribute : $products->count() </div>
@endforeach
@endforeach
--或--
您可以两全其美,只需同时执行这两个操作即可附加计数和分组关系:
$brands = \App\Models\Brand::withCount('products')
->with(['products' => function ($query)
return $query->groupBy('extra_attribute');
])->get();
然后您可以访问该品牌的products_count
和分组产品:
$brands->each(function($brand)
$brand->products_count;
$brand->products->each(function($products, $extra_attribute)
// Grouped Products
);
);
【讨论】:
以上是关于groupBy withCount 闭包(Laravel 5.3.26)的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 在 withCount 方法上使用 where 子句