You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:08:04