Laravel 5.5中如何按关联discount表id排序预加载结果?
解决Laravel中带折扣商品按discount.id降序排序的问题
嘿,我来帮你搞定这个需求!你现在用has('discount')筛选出有折扣的商品,但直接用orderBy('discount.id', 'desc')不会生效——因为has()只是做存在性检查,并没有将discounts表和products表关联到主查询中。下面给你两种靠谱的实现方式:
方法一:使用Join关联表(推荐,性能更优)
通过join()把products和discounts表关联起来,这样就能直接用discounts.id来排序了。如果一个商品对应多个折扣,记得加distinct()避免重复返回:
public function promotions() { return $this->prepareResult(true, Product::join('discounts', 'products.id', '=', 'discounts.product_id') ->where([ 'products.company_id' => 1, 'products.is_active' => 1 ]) ->select('products.*') // 只选商品表字段,避免字段冲突 ->orderBy('discounts.id', 'desc') ->with('category') ->distinct() // 处理一对多关联下的重复数据 ); }
方法二:使用子查询排序(无需Join)
如果不想用Join,可以在orderByRaw()里写一个子查询,获取每个商品对应的最新折扣ID,再以此排序:
public function promotions() { return $this->prepareResult(true, Product::has('discount') ->where([ 'company_id' => 1, 'is_active' => 1 ]) ->with('category') ->orderByRaw('(SELECT id FROM discounts WHERE discounts.product_id = products.id ORDER BY id DESC LIMIT 1) DESC') ); }
注意事项
- 如果你的商品和折扣是一对一关联,方法一里的
distinct()可以去掉; - 如果是一对多关联,方法二的子查询会取每个商品的最大折扣ID来排序,确保结果符合“按discount.id降序”的预期。
内容的提问来源于stack exchange,提问作者Muhammad Abbas
相关产品推荐
相关产品推荐

