Laravel中hasMany关联下如何按最新销售记录查询并排序库存商品
首先修正模型关联错误
你当前SellRecord模型的inventory关联外键参数填写错误,第二个参数应为销售记录表关联库存表的外键字段product_id,修正后代码如下:
public function inventory() { return $this->belongsTo('App\Models\Inventory\Inventory', 'product_id'); }
方案1:使用 Laravel 8+ 内置的 latestOfMany 实现(推荐)
Laravel 8.x 及以上版本提供了latestOfMany方法,专门用于获取一对多关联中最新的一条记录。
- 先在
Inventory模型中新增最新销售记录的一对一关联:
// 新增最新销售记录关联 public function latestSellRecord() { return $this->hasOne('App\Models\Inventory\SellRecord', 'product_id')->latestOfMany(); }
- 实现查询逻辑,支持按最新销售日期排序:
$inventoryList = Inventory::with('latestSellRecord') // 按最新销售记录日期降序排序,没有销售记录的商品会排在最后 ->leftJoin('inventory_sell_records', 'inventory.id', '=', 'inventory_sell_records.product_id') ->selectRaw('inventory.*, MAX(inventory_sell_records.created_at) as latest_sold_at') ->groupBy('inventory.id') ->orderBy('latest_sold_at', 'desc') ->get();
如果需要排除没有销售记录的库存商品,可以在查询中增加whereHas条件:
$inventoryList = Inventory::with('latestSellRecord') ->whereHas('latestSellRecord') ->join('inventory_sell_records', 'inventory.id', '=', 'inventory_sell_records.product_id') ->selectRaw('inventory.*, MAX(inventory_sell_records.created_at) as latest_sold_at') ->groupBy('inventory.id') ->orderBy('latest_sold_at', 'desc') ->get();
方案2:兼容低版本Laravel的子查询实现
如果你使用的Laravel版本低于8.x,没有latestOfMany方法,可以用子查询的方式实现:
$inventoryList = Inventory::select(['inventory.*']) // 子查询关联最新的销售记录 ->addSelect([ 'latest_sold_at' => SellRecord::selectRaw('MAX(created_at)') ->whereColumn('product_id', 'inventory.id') ]) ->with(['sellRecord' => function($query) { // 只取每个商品最新的一条销售记录 $query->whereRaw('created_at = (SELECT MAX(created_at) FROM inventory_sell_records WHERE product_id = inventory_sell_records.product_id)'); }]) ->orderBy('latest_sold_at', 'desc') // 需要排除无销售记录的商品可取消下方注释 // ->whereRaw('EXISTS (SELECT 1 FROM inventory_sell_records WHERE product_id = inventory.id)') ->get();
内容的提问来源于stack exchange,提问作者bohdan baida
相关产品推荐
相关产品推荐

