如何筛选出最后添加子订单的用户为指定ID的订单?
如何筛选出最后添加子订单的用户为指定ID的订单?
嘿,我完全懂你的困扰!你现在写的代码其实只是在找那些曾经有用户123添加过子订单的订单,但根本没验证123是不是最后一个添加子订单的人——这就是为啥结果不符合预期的原因。
咱们的核心思路得调整:先找到每个订单的最后一条子订单,再判断这条子订单的user_id是不是123。下面给你两种实用的写法:
方法一:子查询关联(贴近原生SQL的Eloquent实现)
$myuserid = 123; $orders = Order::query() ->joinSub( // 子查询:先找出每个订单的最后一条子订单ID Suborder::select('order_id', DB::raw('MAX(id) as last_suborder_id')) ->groupBy('order_id'), 'last_suborders', function ($join) { $join->on('orders.id', '=', 'last_suborders.order_id'); } ) // 关联子订单表,拿到最后一条子订单的完整数据 ->join('suborders', 'suborders.id', '=', 'last_suborders.last_suborder_id') // 筛选最后一条子订单的用户ID是指定值 ->where('suborders.user_id', $myuserid) ->select('orders.*') // 只保留订单表的字段 ->get();
方法二:用Eloquent关联优化代码可读性
先在Order模型里定义一个关联,专门指向它的最后一条子订单:
// 在Order模型文件中添加 public function latestSuborder() { return $this->hasOne(Suborder::class)->latest('id'); }
之后就可以用这个关联轻松筛选了:
$myuserid = 123; $orders = Order::query() ->whereHas('latestSuborder', function ($query) use ($myuserid) { $query->where('user_id', $myuserid); }) ->get();
这种写法更贴合Eloquent的风格,读起来更直观。它会自动帮我们定位每个订单的最后一条子订单,再判断这条子订单的用户ID是否为123。
最后再给你捋下原代码的问题:你在whereHas闭包里只针对当前订单下用户123的子订单取最新的,但没和整个订单的最后一条子订单做对比——哪怕之后有其他用户加了子订单,只要该订单曾经有123的子订单,就会被筛出来,这自然不是你想要的结果。
备注:内容来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

