Laravel Eloquent:按小时抽取统计记录(24小时共24条)
用Eloquent实现每小时一条的统计数据查询
嘿,这个需求我之前做图表可视化的时候也碰到过,直接拉所有3分钟间隔的数据确实会让图表杂乱不堪,还浪费资源。用Eloquent结合数据库的日期分组功能就能完美解决,给你两个实用方案,按需选择:
方案1:获取每小时的最新一条记录
如果你的图表需要展示每小时最后一次统计的数据(比如每小时第57分钟的那条),可以用子查询先锁定每个小时的最新记录时间,再关联原表拿到对应数据:
use App\Models\Statistic; use Carbon\Carbon; // 子查询:找出过去24小时内每个小时的最新记录时间 $latestPerHour = Statistic::query() ->selectRaw('DATE_FORMAT(created_at, "%Y-%m-%d %H:00:00") as hour, MAX(created_at) as latest_created_at') ->where('created_at', '>=', Carbon::now()->subHours(24)) ->groupBy('hour'); // 关联原表,拿到对应最新记录的统计值 $hourlyStats = Statistic::query() ->joinSub($latestPerHour, 'latest', function ($join) { $join->on('statistics.created_at', '=', 'latest.latest_created_at'); }) ->select('latest.hour', 'statistics.value') // 替换成你的实际统计字段 ->orderBy('latest.hour') ->get();
这个方法能避免MySQL某些模式下,直接分组选取非聚合字段返回随机值的问题,保证你拿到的每个小时数据都是该时段内最新的那条。
方案2:对每小时的数据做聚合计算
如果你的统计数据适合用汇总值展示(比如每小时的平均值、总和),直接用聚合函数会更简单,还能让图表趋势更清晰:
use App\Models\Statistic; use Carbon\Carbon; $hourlyAggregatedStats = Statistic::query() ->where('created_at', '>=', Carbon::now()->subHours(24)) // 格式化时间为整小时,同时计算所需聚合值 ->selectRaw(' DATE_FORMAT(created_at, "%Y-%m-%d %H:00:00") as hour, AVG(value) as average_value, // 可替换为SUM/MAX/MIN等聚合函数 COUNT(*) as total_records ') ->groupBy('hour') ->orderBy('hour') ->get();
这个方案返回的是每小时的汇总数据,不仅大幅减少了返回的记录数,还能让图表展示的趋势更有代表性,非常适合做可视化数据源。
小提示
- 如果用的是PostgreSQL,把
DATE_FORMAT换成TO_CHAR(created_at, 'YYYY-MM-DD HH24:00:00')即可 - 给
created_at字段加索引,能大幅提升过去24小时数据的查询速度 - 调整
subHours(24)可以改变时间范围,比如subDays(7)就能获取过去7天的每小时数据
内容的提问来源于stack exchange,提问作者Lucas Decrock
相关产品推荐
相关产品推荐

