SQL 时间桶是什么
用 SQL 做时序统计时,先把时间戳对齐到桶再聚合:date_trunc 适配 PostgreSQL 一类数据库,ClickHouse 用 toStartOfInterval,通用写法是 floor(epoch(t) 除以窗口秒数) 乘窗口秒数。桶表达式的结果作为 GROUP BY 键,输出的就按时间窗口的统计值。跨库对照时先确认时区与周起点规则,口径固定后把桶表达式封装成视图或函数,避免每处重写。
基本信息
| 对齐目标 | 把每行时间归入 5 分钟、1 小时、1 天等窗口 |
|---|---|
| 通用思路 | bucket = floor(epoch(t) / 窗口秒数) * 窗口秒数 |
| 函数写法 | date_trunc('hour', ts)(PostgreSQL)、toStartOfInterval(ts, INTERVAL 1 HOUR)(ClickHouse) |
| 所属系统 | 关系型数据库与时序库通用 |
典型使用场景
- 趋势聚合:把明细压成每 5 分钟一个点再画图
- 报表对账:固定左闭右开与对齐起点后跨系统数字才能对上
- 同比环比:以桶为粒度做相邻窗口比较
- 大屏展示:按分钟或小时预聚合成结果表
- 数据补齐:拿到桶序列后在应用侧补零,折线不会断点
通用取整写法
通用取整写法
-- 窗口 300 秒(5 分钟)
SELECT floor(extract(epoch FROM ts) / 300) * 300 AS bucket_s, -- 对齐到 5 分钟
avg(value) AS avg_value, -- 窗口内平均值
count(*) AS samples -- 窗口内采样点数
FROM metrics
WHERE ts >= now() - INTERVAL '1 day'
GROUP BY bucket_s
ORDER BY bucket_s;写法对照
| 写法 | 适用 | 注意 |
|---|---|---|
| date_trunc | PostgreSQL、ClickHouse 等 | 结果为时间戳,语义直观 |
| toStartOfInterval | ClickHouse | 支持任意间隔 |
| floor(epoch/sec)*sec | 通用 | 注意时区与整数除法 |
| GROUP BY 桶 | 所有库 | 桶表达式要写全或使用子查询别名 |
| 时区处理 | 跨时区报表 | 用带时区的时间列避免错位 |
跨库对照时先确认时区与周起点规则;报表口径固定后把桶表达式封装成视图或函数,避免每处重写导致口径漂移。
按秒取整的计算在时区或夏令时切换日会出现错位,跨时区报表应使用带时区的时间列。
桶边界规则不一致会让相邻系统对不上数,先统一左闭右开与对齐起点,再讨论数字差异。