시계열 함수
버킷 · 집계 · 보간 · 회귀를 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_* 를 쓰십시오장비가 재부팅되면 누적 카운터는 0 으로 돌아갑니다. 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의 시간 범위와 같아야 합니다. 다르면 원하지 않은 구간까지 버킷이 생깁니다.
함께 보기
- CQL 로 질의하기 — 접속과 기본 문법
- 계층형 저장 — 압축된 과거도 같은 질의로 읽힙니다