You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:37:04