时序函数
用一行 CQL 完成分桶 · 聚合 · 插值 · 回归。无需单独安装,也无需注册 UDF —— 它们是数据库内置的原生函数。
最常用的写法
-- 시간별 평균, 빈 버킷은 직전 값으로 채운다
SELECT time_bucket_gapfill(1h, timestamp, '2026-07-01', '2026-07-02'),
locf(avg(value))
FROM pp.tm_tag_point
WHERE tag_id = 'TAG-001'
AND timestamp >= '2026-07-01' AND timestamp < '2026-07-02'
GROUP BY tag_id, time_bucket_gapfill(1h, timestamp, '2026-07-01', '2026-07-02')
ORDER BY timestamp ASC;
🔴 请遵守参数顺序。 时序聚合大多遵循 (값, 시각) 的顺序 —— 与 avg(value) 那样仅接收一个值的标准聚合不同。
函数列表
分桶与补缺
| 函数 | 签名 | 返回值 | 说明 |
|---|---|---|---|
time_bucket | time_bucket(간격, ts [, 기준시각]) | timestamp | 桶起始时间。用于降采样的标量 |
time_bucket_gapfill | time_bucket_gapfill(폭, ts, 시작, 끝) | timestamp | 用于 GROUP BY。即使空桶也会生成 |
locf | locf(집계) | 与参数类型相同 | 用前一值填充空桶(last observation carried forward) |
interpolate | interpolate(집계) | double | 用前后线性插值填充空桶 |
取值与变化量
| 函数 | 签名 | 说明 |
|---|---|---|
first / last | first(값, ts) / last(값, ts) | 时间上最早 / 最晚的值 |
delta | delta(값, ts) | 最后 − 最初 |
rate | rate(값, ts) | delta ÷ 经过秒数(以两端点为基准) |
derivative | derivative(값, ts) | 最小二乘回归斜率,每秒 |
counter_delta / counter_rate | (값, ts) | 累计计数器增量 / 每秒增长率。会校正重置 |
累计计数器请使用
counter_*设备重启后,累计计数器会归零。delta 会将其读作“负变化”导致数据损坏,而 counter_delta · counter_rate 能识别并校正重置。
统计与分布
| 函数 | 签名 | 说明 |
|---|---|---|
percentile | percentile(값, q) — q 是 [0,1] | 精确的连续百分位数(线性插值) |
time_weighted_average | (값, ts) | 时间加权平均值 |
integral | (값, ts) | 曲线下方面积(值·秒) |
variance / stddev | (값) | 样本方差 / 标准差 |
histogram | (값, 최소, 최대, 버킷수) | 等宽直方图。长度为 버킷수+2 |
approx_count_distinct | (값) | 近似唯一值数量 |
time_weighted_average 与 avg 不同如果传感器不是按固定间隔上报,简单平均值会被“频繁上报的区间”拉偏。必须按值保持的时间加权,才能得到物理上合理的平均值。
双变量关系
| 函数 | 说明 |
|---|---|
corr(y, x) | 相关系数 |
covar_pop(y, x) / covar_samp(y, x) | 总体协方差 / 样本协方差 |
regr_slope(y, x) / regr_intercept(y, x) / regr_r2(y, x) | y 对 x 回归的斜率 · 截距 · 决定系数 |
示例
按 5 分钟分桶降采样
SELECT time_bucket(5m, timestamp) AS bucket,
avg(value), min(value), max(value)
FROM pp.tm_tag_point
WHERE tag_id = 'TAG-001'
AND timestamp >= '2026-07-01' AND timestamp < '2026-07-02'
GROUP BY tag_id, time_bucket(5m, timestamp);
填充空白区间,让图表没有缺口
SELECT time_bucket_gapfill(10m, timestamp, '2026-07-01', '2026-07-01 06:00'),
interpolate(avg(value))
FROM pp.tm_tag_point
WHERE tag_id = 'TAG-001'
AND timestamp >= '2026-07-01' AND timestamp < '2026-07-01 06:00'
GROUP BY tag_id, time_bucket_gapfill(10m, timestamp, '2026-07-01', '2026-07-01 06:00');
locf 是保持前一值(阶梯),interpolate 是线性插值(直线)。
对于设备状态值这类“在下次变化前保持不变”的信号,适合用 locf;对于温度这类连续物理量,适合用 interpolate。
产量计数器的每小时增长率
SELECT time_bucket(1h, timestamp) AS bucket,
counter_rate(value, timestamp) * 3600 AS per_hour
FROM pp.tm_tag_point
WHERE tag_id = 'COUNTER-01'
AND timestamp >= '2026-07-01' AND timestamp < '2026-07-02'
GROUP BY tag_id, time_bucket(1h, timestamp);
响应延迟的 p95
SELECT time_bucket(1h, timestamp), percentile(value, 0.95)
FROM pp.tm_tag_point
WHERE tag_id = 'LATENCY-01'
AND timestamp >= '2026-07-01' AND timestamp < '2026-07-02'
GROUP BY tag_id, time_bucket(1h, timestamp);
查看两个标签的相关性
SELECT corr(a.value, b.value)
FROM pp.tm_tag_point_pair
WHERE pair_id = 'TEMP-VS-POWER'
AND timestamp >= '2026-07-01' AND timestamp < '2026-07-08';
注意事项
- 请先缩小分区范围再使用函数。前提是在
WHERE中指定分区键(通常是tag_id)和时间范围 —— 否则会扫描所有节点。 - 在
GROUP BY中需同时写入分区键和分桶函数(GROUP BY tag_id, time_bucket(...))。 - 补缺的
시작·끝必须与WHERE的时间范围一致。否则会在不想要的区间也生成桶。