laravel 11 中查询每日数据应优先用 wherebetween 配合 carbon 起止时间以保障索引性能,次选 wheredate(需注意索引失效),聚合统计用 group by date(),展示格式通过模型访问器统一处理。

在 Laravel 11 中处理时间戳字段查询每日数据,关键不是“把时间转成字符串再 like”,而是利用数据库原生能力 + Carbon 的语义化支持,让查询既准确又高效。
用 whereDate() 精确匹配某天(推荐但注意索引)
这是最直观的方式,适合中小数据量或已建好索引的场景:
- 语法简洁:`Log::whereDate('created_at', '2026-10-20')->get()`
- 语义清晰:直接表达“查今天的数据”,比手动拼 `BETWEEN` 更易读
-
注意索引失效风险:MySQL 对 `whereDate(created_at, ?)` 不会使用 `created_at` 单列索引;若该字段高频按日查询,应建复合索引如
(created_at)并配合whereBetween替代,或改用函数索引(MySQL 8.0+)
用 whereBetween 配合 Carbon 起止时间(兼顾性能与兼容性)
更可控、索引友好,是生产环境首选:
- 获取当天起止时间:
$start = now()->startOfDay(); $end = now()->endOfDay(); - 查询写法:
Log::whereBetween('created_at', [$start, $end])->get() - 数据库能直接命中
created_at字段的 B-tree 索引,无需额外配置函数索引 - 适用于跨时区场景:可先用
Carbon::parse($time)->timezone('Asia/Shanghai')统一转换后再计算起止
聚合统计每日数据(group by date)
要统计每天记录数、平均值等,别用 PHP 循环遍历,交给数据库聚合:
Log::selectRaw('DATE(created_at) as date, COUNT(*) as count')<br> ->where('created_at', '>=', now()->subDays(7))<br> ->groupBy('date')<br> ->orderBy('date')<br> ->get();- 返回结果中
date是字符串格式(如"2026-10-20"),无需 PHP 再格式化 - 如需补全无数据的日期(如日历图),可在应用层生成日期序列后 left join 或用 collection->mapWithKeys 合并
模型访问器自动格式化输出(仅用于展示,不影响查询)
如果前端需要统一显示“10月20日”,不要在控制器里反复调用 format(),用访问器封装:
- 在模型中定义:
public function getCreatedAtDateAttribute() { return $this->created_at?->format('m-d'); } - 使用时:
$log->created_at_date,或加到$appends自动包含 - 注意:访问器只影响
toArray()和 JSON 输出,不参与数据库查询逻辑











