使用Carbon按created_at分组统计时如何补全空缺月份数据为0
实现方案
你可以通过生成统计时间范围内所有的连续月份列表,设置默认值为0后和统计结果合并即可,同时可以优化原有统计逻辑的性能,避免全表查询用户数据:
// 1. SQL层面直接完成分组统计,避免加载全量用户数据 $statData = User::query() ->selectRaw("DATE_FORMAT(created_at, '%Y %b') as month, COUNT(*) as user_count") ->groupBy('month') ->pluck('user_count', 'month') ->toArray(); // 2. 确定统计的时间范围,示例取最早用户创建时间到当前月,可自行替换为指定起止时间 $startMonth = Carbon::parse(User::min('created_at'))->startOfMonth(); $endMonth = Carbon::now()->endOfMonth(); // 3. 生成范围内所有月份的默认数组,初始值均为0 $fullMonthList = []; for ($current = $startMonth; $current->lte($endMonth); $current->addMonth()) { $monthKey = $current->format('Y M'); $fullMonthList[$monthKey] = 0; } // 4. 合并统计结果,有数据的月份覆盖默认0值 $res = array_merge($fullMonthList, $statData); // 最终返回结果 return response()->json([ 'message' => 'Data Fetched', 'res' => $res ]);
补充说明
- 如果你需要固定统计某一段周期的月份,直接替换
$startMonth和$endMonth为你指定的时间即可,比如$startMonth = Carbon::parse('2021-01-01') - 原有逻辑中
User::all()在用户量大时会占用大量内存,SQL层面分组统计的性能提升非常明显
内容的提问来源于stack exchange,提问作者David Fim
相关产品推荐
相关产品推荐

