Laravel中按产品分组并获取最低价格变体的数据查询问题
查询每个产品价格最低的变体(Laravel方案)
表结构说明
我有两张表:
products:存储产品基础数据varients:存储产品的规格变体
varients表结构
| id | product_id | varientName | price |
|---|---|---|---|
| 1 | 1 | 2kg | 100 |
| 2 | 1 | 1kg | 50 |
| 3 | 1 | 5kg | 480 |
| 4 | 2 | 250g | 25 |
| 5 | 2 | 100g | 10 |
| 6 | 2 | 500g | 50 |
products表结构
| id | Name |
|---|---|
| 1 | rice |
| 2 | tea |
需求
查询每个产品价格最低的变体,例如得到rice 1kg(50)、tea 100g(10)这类数据。
我尝试的错误代码
$bestSellingProduct = DB::table('products') ->join('varients', 'products.id', '=', 'varients.product_id') ->select('products.product_id','products.name','varients.varientName','varients.id','varients.price') ->orderBy('varients.varientPrice','ASC') ->groupby('products.id') ->get();
问题分析
- 字段错误:
products.product_id不存在(products表主键是id);varients.varientPrice应为varients.price - 逻辑错误:
groupBy会先聚合数据,之后的orderBy只能对聚合结果排序,无法保证取到每组中价格最低的变体 - 未过滤最低价格:仅简单按产品分组,没有筛选出每个产品价格最低的那条变体记录
正确的Laravel查询方案
方案1:子查询关联筛选
直接通过子查询获取每个产品的最低价格,再关联变体表匹配对应记录:
$lowestPriceVariants = DB::table('products') ->join('varients', function ($join) { $join->on('products.id', '=', 'varients.product_id') ->whereColumn('varients.price', '=', DB::raw('(SELECT MIN(price) FROM varients WHERE product_id = products.id)')); }) ->select('products.name', 'varients.varientName', 'varients.price') ->get();
方案2:先分组获取最低价格,再关联查询
先统计每个产品的最低价格,再通过两次关联匹配对应的变体信息:
// 先获取每个产品的最低价格 $minPriceSubquery = DB::table('varients') ->select('product_id', DB::raw('MIN(price) as min_price')) ->groupBy('product_id'); // 关联查询获取对应变体 $lowestPriceVariants = DB::table('products') ->joinSub($minPriceSubquery, 'min_prices', function ($join) { $join->on('products.id', '=', 'min_prices.product_id'); }) ->join('varients', function ($join) { $join->on('products.id', '=', 'varients.product_id') ->on('varients.price', '=', 'min_prices.min_price'); }) ->select('products.name', 'varients.varientName', 'varients.price') ->get();
方案3:Eloquent模型关联方式(若使用模型)
假设已定义Product和Varient模型,并建立关联:
// Product模型 class Product extends Model { public function varients() { return $this->hasMany(Varient::class); } }
查询代码:
$lowestPriceVariants = Product::with(['varients' => function ($query) { // 筛选当前产品价格最低的变体 $query->where('price', '=', function ($subquery) { $subquery->select(DB::raw('MIN(price)')) ->from('varients') ->whereColumn('product_id', 'products.id'); }); }])->get()->map(function ($product) { // 整理输出格式 return [ 'product_name' => $product->name, 'varient' => $product->varients->first()->varientName, 'lowest_price' => $product->varients->first()->price ]; });
内容的提问来源于stack exchange,提问作者M kumar
相关产品推荐
相关产品推荐

