TDengine 窗口完整语法 — INTERVAL/SESSION/STATE/EVENT/COUNT 详解

分类:10.SQL 参考 | 篇章:05 窗口完整语法
在这里插入图片描述

适用版本:TDengine v3.x(v3.3.x / v3.4.x) | 最后更新:2026-07-18

窗口子句是 TDengine 最具特色的语法。本文按窗口类型逐一详解语法、参数、约束、典型使用模式。

窗口语法速查

类型语法
INTERVALINTERVAL(duration [, offset]) [SLIDING(duration)]
SESSIONSESSION(ts_column, gap)
STATESTATE_WINDOW(state_column)
EVENTEVENT_WINDOW START WITH expr END WITH expr
COUNTCOUNT_WINDOW(count [, sliding_count])
FILL`FILL(NULL

详细解析

1. INTERVAL 完整语法

INTERVAL(duration [, offset])
[SLIDING(duration)]
[FILL(...)]

-- duration: 窗口时长,支持 b/u/a/s/m/h/d/w/n/y
-- offset:   起始偏移(用于非自然对齐)
-- SLIDING:  滑动步长(必须 ≤ INTERVAL)


-- 示例
INTERVAL(1m)                     -- 每分钟
INTERVAL(1h)                     -- 每小时(00:00 对齐)
INTERVAL(1d)                     -- 每天(00:00 当地时间)
INTERVAL(1d, 8h)                 -- 每天但从 08:00 开始
INTERVAL(1h) SLIDING(15m)        -- 1 小时窗口,每 15 分钟一个
INTERVAL(5m) SLIDING(1m)         -- 5 分钟窗口,每分钟产出


-- 时间单位:
-- b: 纳秒 (ns)
-- u: 微秒 (us)
-- a: 毫秒 (ms)
-- s: 秒
-- m: 分钟
-- h: 小时
-- d: 天
-- w: 周
-- n: 月
-- y: 年

2. SESSION 窗口

SESSION(ts_column, gap)

-- ts_column: 时间列(通常 ts)
-- gap:       会话切分阈值


-- 示例
SESSION(ts, 30m)                 -- 30 分钟无数据切分
SESSION(ts, 1h)                  -- 1 小时切分

-- 用法
SELECT _wstart, _wend, COUNT(*), MAX(value) 
FROM events 
SESSION(ts, 30m);


-- 行为:
-- 相邻两行 ts 差 > gap → 切分新窗口
-- 数据稀疏时窗口少,密集时窗口多

3. STATE 窗口

STATE_WINDOW(state_column)

-- state_column: 状态列(整数或字符串)

-- 示例
SELECT _wstart, _wend, status, COUNT(*) 
FROM machine_log 
STATE_WINDOW(status);


-- 行为:
-- state_column 值变化 → 切分窗口
-- 同一值连续行合并为一个窗口


-- 约束:
-- state_column 不能是 TIMESTAMP/FLOAT
-- 必须是 INT 或 VARCHAR/NCHAR

4. EVENT 窗口

EVENT_WINDOW 
  START WITH expression 
  END WITH expression

-- expression: 任意布尔表达式(基于行数据)


-- 示例
SELECT _wstart, _wend, MAX(temperature) 
FROM sensor 
EVENT_WINDOW 
  START WITH temperature > 80 
  END WITH temperature < 60;


-- 行为:
-- 满足 START 条件 → 窗口开始
-- 满足 END 条件 → 窗口结束
-- 期间所有行属于该窗口


-- 注意:
-- 同一行可能同时满足 START 和 END
-- 不在窗口期内的数据被忽略

5. COUNT 窗口

COUNT_WINDOW(count [, sliding_count])

-- count:         窗口大小(行数)
-- sliding_count: 滑动行数(可选)


-- 示例
COUNT_WINDOW(100)                -- 每 100 行一个窗口
COUNT_WINDOW(100, 50)            -- 滑动 50 行


-- 行为:
-- 累积 count 行后输出窗口
-- 不依赖时间(按行数)
-- 适合等量采样

6. FILL 选项

-- 仅 INTERVAL/SESSION 等时间相关窗口支持
INTERVAL(1h) FILL(fill_mode)

-- fill_mode:
FILL(NULL)             -- 空窗口为 NULL
FILL(VALUE, 0)         -- 空窗口为指定值
FILL(VALUE, 0, 1)      -- 多列分别指定
FILL(PREV)             -- 复用前值
FILL(NEXT)             -- 用后值
FILL(LINEAR)           -- 线性插值
FILL(NONE)             -- 跳过空窗口(默认)


-- 示例
SELECT _wstart, AVG(current) 
FROM meters 
WHERE ts > now-1h 
INTERVAL(1m) 
FILL(LINEAR);


-- LINEAR 需要前后非空窗口
-- 头部/尾部空窗口可能退化为 PREV/NEXT 行为

7. PARTITION BY + 窗口

-- 最常见组合:每子表各自窗口聚合
SELECT tbname, _wstart, AVG(current) 
FROM meters 
PARTITION BY tbname 
INTERVAL(1h);


-- 多列分区
SELECT location, groupid, _wstart, AVG(current) 
FROM meters 
PARTITION BY location, groupid 
INTERVAL(1h);


-- 行为:
-- 每个 partition 独立窗口聚合
-- 输出:每个 (partition, _wstart) 一行

8. 窗口元数据列

SELECT 
  _wstart,           -- 窗口开始时间
  _wend,             -- 窗口结束时间
  _wduration,        -- 窗口时长(毫秒)
  _qstart,           -- 查询时间范围开始
  _qend,             -- 查询时间范围结束
  COUNT(*)
FROM meters 
WHERE ts BETWEEN '2026-06-01' AND '2026-06-02' 
INTERVAL(1h);


-- 输出示例:
-- _wstart              _wend                _wduration  _qstart              _qend                count
-- 2026-06-01 00:00:00  2026-06-01 01:00:00  3600000     2026-06-01 00:00:00  2026-06-02 00:00:00  100
-- ...

代码示例

综合应用

-- 设备小时级监控(含填充)
SELECT 
  tbname, 
  _wstart AS hour,
  AVG(current) AS avg_c,
  MAX(current) AS max_c,
  COUNT(*) AS samples 
FROM meters 
WHERE ts BETWEEN '2026-06-01' AND '2026-06-08' 
  AND location IN ('Beijing', 'Shanghai')
PARTITION BY tbname 
INTERVAL(1h) 
FILL(LINEAR);


-- 用户会话分析
SELECT 
  user_id, 
  _wstart AS session_start,
  _wend AS session_end,
  _wduration / 1000 AS duration_sec,
  COUNT(*) AS actions 
FROM user_action 
PARTITION BY user_id 
SESSION(ts, 30m);


-- 设备状态切换
SELECT 
  tbname,
  _wstart AS state_start,
  _wend AS state_end,
  status,
  _wduration AS duration 
FROM machine_log 
PARTITION BY tbname 
STATE_WINDOW(status);


-- 异常温度事件
SELECT 
  tbname,
  _wstart, _wend,
  MAX(temperature) AS peak,
  COUNT(*) AS samples 
FROM sensor 
WHERE ts > now-7d 
PARTITION BY tbname 
EVENT_WINDOW 
  START WITH temperature > 80 
  END WITH temperature < 60;


-- 滑动统计
SELECT 
  _wstart,
  AVG(current) AS rolling_avg,
  MAX(current) AS rolling_max 
FROM meters 
WHERE ts > now-1h 
INTERVAL(15m) SLIDING(1m) 
FILL(NULL);


-- 等量采样
SELECT 
  _wstart, _wend,
  AVG(value), COUNT(*) 
FROM data_stream 
PARTITION BY tbname 
COUNT_WINDOW(1000);

性能考量

各窗口性能特点

窗口状态量输出量复杂度
INTERVAL中等O(N)
INTERVAL+SLIDING极高O(N×slide_factor)
SESSIONO(N)
STATE极低O(N)
EVENT极低O(N)
COUNT极低O(N)

选择建议

业务推荐窗口
时间报表INTERVAL
趋势监控INTERVAL + SLIDING
用户会话SESSION
设备状态时长STATE
异常事件EVENT
等量采样COUNT

FAQ

Q1: SLIDING 必须 ≤ INTERVAL?

是。否则数据会跳过未被覆盖。

Q2: 窗口必须配合 PARTITION BY 吗?

不必。无 PARTITION 时所有数据合并按窗口聚合。

Q3: FILL 对头部/尾部空窗口效果?

LINEAR 需要前后非空窗口,边界情况退化为 NULL 或 PREV/NEXT 行为。

Q4: 嵌套窗口支持吗?

不直接支持。需用子查询:先小窗口聚合,再大窗口聚合。

Q5: 一个查询能用多个窗口吗?

不能。一个查询只能一种窗口类型。需要时用子查询分步。

参考

系统构架篇

数据模型

存储引擎

查询引擎

数据写入

数据订阅

预聚合

索引

SQL 语句

关于 TDengine

TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TDengine (老段)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值