Laravel如何基于关联Merchant模型的最低价格对Product模型排序
你原有写法不生效的核心原因是:with()做关联预加载时,是先执行Product主表查询,再单独查询关联的Merchant数据,主查询阶段并没有关联merchants表,所以直接写orderBy('merchants.price')无法识别字段。而直接join会导致Product重复,是因为单条Product对应多条Merchant记录。
解决方案1(Laravel 8+ 推荐)
使用Laravel内置的withMin快捷聚合方法,直接为每个Product计算关联Merchant的最低价格,再按该字段排序,全程不需要join,不会产生重复数据:
Product::with('merchants') ->whereHas('category', function ($q) use ($highlight) { $q->where('id', $highlight->category_id); }) // 计算每个Product关联Merchant的最低价格,生成临时字段 merchants_min_price ->withMin('merchants', 'price') // 按最低价格升序排序 ->orderBy('merchants_min_price', 'asc') ->get();
解决方案2(兼容低版本Laravel)
直接在排序逻辑中写入子查询,实现效果和上面一致:
Product::with('merchants') ->whereHas('category', function ($q) use ($highlight) { $q->where('id', $highlight->category_id); }) ->orderByRaw('(SELECT MIN(price) FROM merchants WHERE merchants.product_id = products.id) ASC') ->get();
两种方案最终返回的Product列表都不会有重复数据,且会按照每个Product关联的最低Merchant价格升序排列,完全符合你要的排序效果。
内容的提问来源于stack exchange,提问作者Sukhchain Singh
相关产品推荐
相关产品推荐

