首页/数据/NoSQL 速查/SQL 通用时间桶写法

SQL 通用时间桶写法

用 SQL 做时序统计时先把时间戳对齐到桶再聚合:date_trunc 适配 PostgreSQL/ClickHouse,floor 取整适配通用整数运算,两者结果都按桶标签分组。

NoSQL 速查数据更新于 2026-10-13

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_truncPostgreSQL、ClickHouse 等结果为时间戳,语义直观
toStartOfIntervalClickHouse支持任意间隔
floor(epoch/sec)*sec通用注意时区与整数除法
GROUP BY 桶所有库桶表达式要写全或使用子查询别名
时区处理跨时区报表用带时区的时间列避免错位
跨库对照时先确认时区与周起点规则;报表口径固定后把桶表达式封装成视图或函数,避免每处重写导致口径漂移。
按秒取整的计算在时区或夏令时切换日会出现错位,跨时区报表应使用带时区的时间列。
桶边界规则不一致会让相邻系统对不上数,先统一左闭右开与对齐起点,再讨论数字差异。

易错点

  • 按秒取整的计算在时区或夏令时切换日会出现错位,跨时区报表用带时区的时间列
  • 桶边界规则不一致会导致相邻系统对不上数,先统一左闭右开与对齐起点
  • 对时间列做函数运算会让索引失效,能在过滤条件里直接用原始时间列就不要写表达式
  • 窗口粒度小于数据采样周期时只会产生大量空桶,先确认数据精度再定窗口

数据来源与参考

  • PostgreSQL Docs: date_trunc
  • ClickHouse Docs: Date and time functions
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌