Laravel如何实现交易数据按日/月/年分组返回指定结构响应
Laravel 按日/月/年维度分组支付记录实现方案
你可以直接通过Laravel自带的集合分组能力实现需求,不需要写复杂原生SQL,新手也能快速上手。
核心实现逻辑(按年分组,匹配你给出的目标结构)
先查询对应范围的支付记录,再通过集合groupBy方法按时间维度分组,最后映射为要求的数组结构即可,控制器代码示例:
<?php namespace App\Http\Controllers; use App\Models\Payment; use Illuminate\Http\JsonResponse; class PaymentController extends Controller { public function getGroupedPayments(): JsonResponse { // 按需添加查询筛选条件,比如只查已支付记录、指定用户的记录 $payments = Payment::query() ->where('Status', 'paid') // ->where('UserId', auth()->id()) // 如需查当前登录用户的支付可加这行 ->get(); $groupedResult = $payments ->groupBy(fn($payment) => $payment->created_at->year) // 按created_at的年份分组 ->map(fn($yearPayments, $year) => [ 'year' => (string)$year, // 转为字符串匹配要求的格式 'payments' => $yearPayments ]) ->values(); // 重置数组索引,返回标准JSON数组而非对象 return response()->json($groupedResult); } }
扩展:按月、按日分组
只需要修改groupBy的分组规则和返回键名即可:
- 按月分组
$groupedByMonth = $payments ->groupBy(fn($payment) => $payment->created_at->format('Y-m')) // 分组key格式:2022-07 ->map(fn($monthPayments, $month) => [ 'month' => $month, 'payments' => $monthPayments ]) ->values();
- 按日分组
$groupedByDay = $payments ->groupBy(fn($payment) => $payment->created_at->format('Y-m-d')) // 分组key格式:2022-07-13 ->map(fn($dayPayments, $day) => [ 'day' => $day, 'payments' => $dayPayments ]) ->values();
注意事项
- Laravel默认会把模型的
created_at、updated_at字段自动转为Carbon时间实例,所以可以直接调用->year、->format()等时间方法,不需要手动转换。 - 如果你需要用表中的
TransactionDate字段分组,这个字段存储格式是YmdHis的时间字符串,需要先转为Carbon实例再分组,示例:// 首先顶部引入Carbon类 use Carbon\Carbon; // 分组时的逻辑改为 ->groupBy(fn($payment) => Carbon::createFromFormat('YmdHis', $payment->TransactionDate)->year) - 上述集合分组方案适合数据量在10万条以内的场景,代码可读性高、维护成本低;如果你的支付表数据量特别大,可以改用SQL原生的
YEAR()、MONTH()、DATE()函数做数据库层面分组,减少PHP内存占用。
内容的提问来源于stack exchange,提问作者Elias Baya
相关产品推荐
相关产品推荐

