分类:10.SQL 参考 | 篇章:05 窗口完整语法
适用版本:TDengine v3.x(v3.3.x / v3.4.x) | 最后更新:2026-07-18
窗口子句是 TDengine 最具特色的语法。本文按窗口类型逐一详解语法、参数、约束、典型使用模式。
窗口语法速查
| 类型 | 语法 |
|---|---|
| INTERVAL | INTERVAL(duration [, offset]) [SLIDING(duration)] |
| SESSION | SESSION(ts_column, gap) |
| STATE | STATE_WINDOW(state_column) |
| EVENT | EVENT_WINDOW START WITH expr END WITH expr |
| COUNT | COUNT_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) |
| SESSION | 低 | 低 | O(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: 一个查询能用多个窗口吗?
不能。一个查询只能一种窗口类型。需要时用子查询分步。
参考
系统构架篇
- 01-《TDengine 整体架构全景》
- 02-《集群拓扑深度解析》
- 03-《MNode 内部机制深度解析》
- 04-《RPC 通信层深度解析》
- 05-《VNode 生命周期》
- 06-《RAFT 共识协议》
- 07-《端到端的消息流》
数据模型
- 01-《数据库创建与参数详解》
- 02-《超级表/子表/普通表》
- 03-《支持数据类型深度解析》
- 04-《TDengine Tag 设计哲学与 Schema 变更机制》
- 05-《TDengine 虚拟表实现原理》
存储引擎
- 01-《TDengine 存储引擎概览》
- 02-《TDengine MemTable 深度解析》
- 03-《TDengine WAL 预写日志机制》
- 04-《TDengine 数据文件格式》
- 05-《TDengine Commit 与 Flush 机制 》
- 06-《TDengine Compaction 合并策略 》
- 07-《TDengine 数据保留与 TTL》
- 08-《TDengine 压缩编码机制》
- 09-《TDengine Cache 与 Last 查询加速》
- 10-《TDengine 逻辑计划生成》
查询引擎
- 01-《TDengine 查询引擎概览》
- 02-《TDengine SQL 解析与词法分析》
- 03-《TDengine 语义分析与 AST 重写》
- 04-《TDengine 逻辑计划生成》
- 05-《TDengine 物理计划生成》
- 06-《TDengine 扫描算子》
- 07-《TDengine 聚合算子》
- 08-《TDengine 连接算子》
- 09-《TDengine 排序、填充与投影》
- 10-《TDengine 分布式查询执行》
- 11-《TDengine EXPLAIN 与查询优化》
数据写入
- 01-《TDengine SQL INSERT》
- 02-《TDengine 无模式写入》
- 03-《TDengine STMT 写入》
- 04-《TDengine 写入内部流程》
- 05-《TDengine 数据更新删除》
数据订阅
- 01-《TDengine 数据订阅》
- 02-《TDengine 订阅 vs Kafka》
- 03-《TDengine TMQ 消费流程》
- 04-《TDengine 内部机制》
- 05-《TDengine TMQ 最佳实践》
预聚合
索引
SQL 语句
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。


364

被折叠的 条评论
为什么被折叠?



