Laravel 12中查询本月每日数据需先用Carbon获取本月起止时间,再按日期分组统计;若需补全缺失日期(含0值),须在PHP层生成完整日期数组并与查询结果合并。

在 Laravel 12 中查询“本月内每一天的数据记录”,核心是:**按日期分组统计(或补全缺失日期)+ 时间范围限定 + 可能的日期对齐处理**。直接用 whereBetween 只能查出有数据的日期,若某天无记录则不会返回 —— 所以是否需要“补零”(即确保 1–31 日每天都有结果,空数据填 0)是关键前提。
✅ 先获取本月起止时间(Laravel 12 推荐写法)
Laravel 12 基于 Carbon 3,日期操作更严格。推荐用 Carbon 的静态方法获取本月范围:
$start = now()->startOfMonth(); $end = now()->endOfMonth();
这样得到的是带时分秒的 Carbon 实例(如 2024-05-01 00:00:00 和 2024-05-31 23:59:59),可直接用于查询。
✅ 查询有数据的日期(简单聚合,不补零)
适用于只需知道“哪些天有记录、各多少条”:
- 使用
selectRaw提取日期(MySQL 用DATE(created_at),PostgreSQL 用created_at::date) - 用
groupBy按日期分组 - 用
whereBetween限定本月范围
$data = Order::selectRaw('DATE(created_at) as date, COUNT(*) as count')
->whereBetween('created_at', [$start, $end])
->groupBy('date')
->orderBy('date')
->get();
结果形如:[{"date":"2024-05-01","count":3}, {"date":"2024-05-03","count":7}] —— 缺失日期不会出现。
✅ 补全本月所有日期(含 0 条记录的天)
需手动构造完整日期数组,再与查询结果合并。推荐在控制器中处理:
- 生成本月全部日期集合(Carbon 提供
daysInMonth和copy()->addDay()循环) - 将数据库查出的结果转为
date => count的键值对 - 遍历日期数组,用
?? 0填充缺失值
$dates = collect();
for ($d = $start->copy(); $d->lte($end); $d->addDay()) {
$dates->push($d->format('Y-m-d'));
}
$result = Order::selectRaw('DATE(created_at) as date, COUNT(*) as count')
->whereBetween('created_at', [$start, $end])
->groupBy('date')
->pluck('count', 'date'); // → ['2024-05-01' => 3, '2024-05-03' => 7]
$fullData = $dates->mapWithKeys(function ($date) use ($result) {
return [$date => $result[$date] ?? 0];
})->values();
最终 $fullData 是长度为当月天数的数值集合,顺序固定(从 1 日到末日),适合渲染折线图或日历表格。
✅ 进阶:用数据库生成日期序列(MySQL 8.0+/PostgreSQL)
若数据库版本支持(如 MySQL 8.0 的 CTE 或 PostgreSQL 的 generate_series),可交由 SQL 完成补全,减少 PHP 处理。但 Laravel 12 原生不封装这类语法,需用 DB::select 或原生查询,可读性和可移植性下降,中小项目建议用 PHP 补全更稳妥。


















