如何在Laravel中将两类Product查询合并为单个查询?
合并Product查询:同时展示未分组数据与分组统计数据
集合层面处理(推荐)
这种方式先一次性获取所有产品数据,再通过Laravel集合方法拆分未分组数据和带统计的分组数据,代码简洁易维护:
// 获取所有产品数据 $allProducts = Product::all(); // 筛选未分组的产品(category_id 为 null) $ungroupedProducts = $allProducts->whereNull('category_id'); // 处理分组数据,同时计算每个分类的条目数和金额总和 $groupedProducts = $allProducts->whereNotNull('category_id') ->groupBy('category_id') ->map(function ($categoryProducts) { return [ 'category_id' => $categoryProducts->first()->category_id, // 可选:关联Category模型后可获取分类名称 // 'category_name' => $categoryProducts->first()->category->name, 'item_count' => $categoryProducts->count(), 'total_amount' => $categoryProducts->sum('price'), 'products' => $categoryProducts ]; });
视图展示示例(Blade)
{{-- 展示未分组产品 --}} <h3>未分组产品</h3> <ul> @foreach($ungroupedProducts as $product) <li>ID: {{ $product->product_id }} | 名称: {{ $product->name }}</li> @endforeach </ul> {{-- 展示分组产品及统计 --}} <h3>按分类分组产品</h3> @foreach($groupedProducts as $group) <div> <h4>分类ID: {{ $group['category_id'] }} | 条目数: {{ $group['item_count'] }} | 总金额: {{ $group['total_amount'] }}</h4> <ul> @foreach($group['products'] as $product) <li>ID: {{ $product->product_id }} | 名称: {{ $product->name }}</li> @endforeach </ul> </div> @endforeach
数据库单个查询方案
如果希望通过一次数据库查询获取所有数据(包含每个产品对应的分类统计),可以使用子查询关联:
$products = Product::leftJoin( // 子查询获取分类统计数据 Product::whereNotNull('category_id') ->groupBy('category_id') ->selectRaw('category_id, count(*) as item_count, sum(price) as total_amount') ->toBase(), function ($join) { $join->on('products.category_id', '=', 'category_stats.category_id'); } ) ->select('products.product_id', 'products.name', 'products.category_id', 'item_count', 'total_amount') ->get();
视图展示示例(Blade)
每条产品数据自带item_count和total_amount字段,为null时代表未分组产品:
<h3>所有产品</h3> <ul> @foreach($products as $product) <li> ID: {{ $product->product_id }} | 名称: {{ $product->name }} @if($product->category_id) | 分类ID: {{ $product->category_id }} | 分类总条目数: {{ $product->item_count }} | 分类总金额: {{ $product->total_amount }} @endif </li> @endforeach </ul>
注意事项
- 若需展示分类名称,需在
Product模型中定义与Category的关联:
之后可通过public function category() { return $this->belongsTo(Category::class); }$categoryProducts->first()->category->name获取分类名称。 - 确保
price字段为数值类型,避免金额总和计算错误。
内容的提问来源于stack exchange,提问作者Prince
相关产品推荐
相关产品推荐

