Laravel:获取每个用户指定日期的最后一笔交易
解决获取用户特定日期最后一笔交易的问题
原代码的问题在于仅按用户分组,但未对交易时间做降序排序,也没有逻辑确保每组取最后一条记录,因此返回的是默认排序下的第一笔交易。以下是两种可行的修正方案:
方案一:子查询关联法
先获取每个用户在指定日期的最晚交易时间(或最大交易ID,确保唯一性),再关联交易表拿到对应记录:
public function usersLastTransaction(Request $request) { // 子查询:获取每个用户在2023-07-14的最后交易ID(用ID确保时间相同时取最新的) $lastTransactionIds = DB::table('transactions') ->whereDate('created_at', '2023-07-14') ->groupBy('trigered_by') ->select('trigered_by', DB::raw('MAX(id) as last_transaction_id')); // 关联子查询,拿到对应的交易记录 return DB::table('transactions') ->joinSub($lastTransactionIds, 'last_ids', function ($join) { $join->on('transactions.id', '=', 'last_ids.last_transaction_id'); }) ->join('users', 'users.id', '=', 'transactions.trigered_by') ->join('model_has_roles', 'model_has_roles.model_id', '=', 'users.id') ->join('roles', 'roles.id', '=', 'model_has_roles.role_id') ->select('transactions.*') ->get(); }
方案二:窗口函数法(Laravel 8+支持)
利用ROW_NUMBER()窗口函数按用户分组,交易时间降序排序后取每组第一条:
public function usersLastTransaction(Request $request) { return DB::table('transactions') ->select( 'transactions.*', DB::raw('ROW_NUMBER() OVER (PARTITION BY trigered_by ORDER BY created_at DESC, id DESC) as rn') ) ->whereDate('created_at', '2023-07-14') ->join('users', 'users.id', '=', 'transactions.trigered_by') ->join('model_has_roles', 'model_has_roles.model_id', '=', 'users.id') ->join('roles', 'roles.id', '=', 'model_has_roles.role_id') ->having('rn', '=', 1) ->get(); }
注意事项
- 若
created_at存在同一秒多笔交易的情况,建议结合自增ID排序(ORDER BY created_at DESC, id DESC),确保拿到真正最新的那笔。 - 确保
transactions.created_at字段为datetime或timestamp类型,能正确进行时间比较。
内容的提问来源于stack exchange,提问作者Sangam Kumar
相关产品推荐
相关产品推荐

