Laravel 5.6:如何按order_id获取各订单的最新唯一记录
获取每个order_id的最新记录(Laravel Eloquent方案)
要获取每个order_id对应的最新记录(也就是created_at字段值最大的那条),你可以用以下几种Eloquent查询方式来实现,根据你的数据库版本和需求选择即可:
方案1:使用JOIN关联子查询(兼容性好)
这种方法通过子查询先找出每个order_id的最新创建时间,再关联原表匹配对应的完整记录,适合所有主流数据库版本:
$latestOrders = OrderAttempt::join( // 子查询:分组获取每个order_id的最新created_at \DB::raw('(SELECT order_id, MAX(created_at) as latest_created FROM order_attempts GROUP BY order_id) as latest_orders'), function ($join) { $join->on('order_attempts.order_id', '=', 'latest_orders.order_id') ->on('order_attempts.created_at', '=', 'latest_orders.latest_created'); } ) ->select('order_attempts.*') // 只取原表的字段 ->get();
方案2:使用窗口函数(MySQL 8+/PostgreSQL等现代数据库)
如果你的数据库支持窗口函数(比如MySQL 8.0及以上版本),可以用更简洁的写法:
$latestOrders = OrderAttempt::selectRaw('*, ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY created_at DESC) as row_num') ->having('row_num', '=', 1) // 只保留每个分组里的第一条(最新的那条) ->get();
这里的PARTITION BY order_id会按订单ID分组,ORDER BY created_at DESC让每组内最新的记录排在前面,最后筛选出row_num=1的记录就是我们要的结果。
方案3:使用Eloquent的whereExists子查询
另一种更“Eloquent风格”的写法,通过whereExists来匹配每个订单的最新记录:
$latestOrders = OrderAttempt::whereExists(function ($query) { $query->select(\DB::raw(1)) ->from('order_attempts as oa') ->whereColumn('oa.order_id', 'order_attempts.order_id') ->groupBy('oa.order_id') ->havingRaw('MAX(oa.created_at) = order_attempts.created_at'); })->get();
以上三种方法都能得到你需要的结果:order_id=1对应2018-03-04的Message #4,order_id=2对应2018-03-03的Message #3。
内容的提问来源于stack exchange,提问作者D.R.
相关产品推荐
相关产品推荐

