在 laravel 8 中用 db::raw() 按日期统计每日数据,需用 date() 或 date_format() 提取日期并分组,select 和 groupby 均须用 db::raw(),不可用别名,且需注意数据库函数兼容性。

在 Laravel 8 中,用 DB::raw() 按日期统计每日数据,核心是借助数据库的日期函数(如 MySQL 的 DATE()、DATE_FORMAT())对时间字段做分组,并配合 groupBy 和聚合函数(如 COUNT()、SUM())完成统计。
使用 DATE() 提取日期并分组(推荐,兼容性好)
假设你有一个 orders 表,含 created_at 时间戳字段,想统计每天下单数量:
$dailyStats = DB::table('orders')
->select(
DB::raw('DATE(created_at) as date'),
DB::raw('COUNT(*) as count')
)
->groupBy(DB::raw('DATE(created_at)'))
->orderBy('date', 'desc')
->get();
✅ 说明:
- DATE(created_at) 会把 2023-05-12 14:30:22 转为 2023-05-12(仅日期)
- groupBy(DB::raw('DATE(created_at)')) 是关键,不能只写 groupBy('date')(别名在 groupBy 中不可用)
- 结果中 date 是字符串格式的日期,可直接用于前端展示
按年月日格式化分组(如 'Y-m-d')
如果需要更灵活的格式(比如带前导零),可用 DATE_FORMAT()(MySQL):
$dailyStats = DB::table('orders')
->select(
DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d') as date"),
DB::raw('COUNT(*) as count')
)
->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m-%d')"))
->orderBy('date')
->get();
⚠️ 注意:
- DATE_FORMAT 是 MySQL 特有函数,SQLite 或 PostgreSQL 不支持(PostgreSQL 用 TO_CHAR(created_at, 'YYYY-MM-DD'))
- 单引号必须在双引号内转义,或改用 sprintf 避免混淆
补充实用技巧
-
限定时间范围:加
whereBetween('created_at', [$start, $end])避免全表扫描 -
处理空日期:若
created_at允许为 NULL,加whereNotNull('created_at') -
关联其他字段统计:比如统计每天的订单总金额:
DB::raw('SUM(total_price) as amount') -
返回数组而非对象:链式调用
->toArray(),适合 JSON 输出
常见问题提醒
❌ 错误写法:->groupBy('date') —— 别名不能用于 groupBy,会报 “Unknown column 'date'”
❌ 忘记 select 中的 DB::raw() —— 直接写 'DATE(created_at)' 会被当成字符串字面量
✅ 正确姿势:所有参与计算/格式化的字段,select 和 groupBy 都要用 DB::raw() 显式声明











