TDengine JOIN 完整语法 — Inner/Outer/ASOF/Window 全语法详解

发布时间:2026/7/17 18:56:15
TDengine JOIN 完整语法 — Inner/Outer/ASOF/Window 全语法详解 分类10.SQL 参考 |篇章04 JOIN 完整语法适用版本TDengine v3.xv3.3.x / v3.4.x | 最后更新2026-07-17TDengine JOIN 在标准 SQL 基础上扩展了时序专属的 ASOF 和 Window JOIN。本文是 JOIN 语法的完整参考含每种类型的语义、条件约束、典型用例。JOIN 类型速查表类型关键字行为InnerJOIN / INNER JOIN双侧匹配Left OuterLEFT JOIN / LEFT OUTER JOIN保留左侧Right OuterRIGHT JOIN / RIGHT OUTER JOIN保留右侧Full OuterFULL JOIN / FULL OUTER JOIN保留双侧SemiLEFT SEMI JOIN左侧存在匹配则保留AntiLEFT ANTI JOIN左侧无匹配则保留ASOFLEFT ASOF JOIN时间近邻WindowWINDOW JOIN时间窗口对齐详细解析1. 时间条件约束重要所有 JOIN 必须满足时间相关性 ✓ 普通 JOIN必须含 t1.ts t2.ts 或时间等值 ✓ ASOF JOIN必须含 t1.ts op t2.ts 时间比较 ✓ WINDOW JOIN内置时间窗口 ✗ 不允许的 JOIN SELECT * FROM t1 JOIN t2 ON t1.id t2.id; -- 缺时间2. Inner JOIN-- 基本SELECTt1.ts,t1.current,t2.powerFROMelectric_meters t1JOINpower_meters t2ONt1.tst2.ts;-- 多条件SELECT*FROMt1JOINt2ONt1.tst2.tsANDt1.locationt2.location;-- 多表注意性能SELECT*FROMt1JOINt2ONt1.tst2.tsJOINt3ONt1.tst3.ts;语义 保留ON条件同时满足的行 双侧 ts 都存在且相等3. Outer JOIN-- LEFT JOINSELECTt1.ts,t1.current,t2.powerFROMelectric_meters t1LEFTJOINpower_meters t2ONt1.tst2.ts;-- t1 保留所有t2 无匹配为 NULL-- RIGHT JOINSELECTt1.ts,t1.current,t2.powerFROMelectric_meters t1RIGHTJOINpower_meters t2ONt1.tst2.ts;-- t2 保留所有-- FULL OUTER JOINSELECTt1.ts,t1.current,t2.powerFROMelectric_meters t1FULLJOINpower_meters t2ONt1.tst2.ts;-- 双侧都保留4. Semi/Anti JOIN-- SEMI JOIN: 左侧存在匹配则保留去重SELECT*FROMusers uLEFTSEMIJOINorders oONu.ido.user_idANDu.tso.ts;-- 等价于SELECT * FROM users WHERE id IN (SELECT user_id FROM orders)-- ANTI JOIN: 左侧无匹配则保留SELECT*FROMusers uLEFTANTIJOINorders oONu.ido.user_idANDu.tso.ts;-- 等价于SELECT * FROM users WHERE id NOT IN (...)5. ASOF JOIN时间近邻-- LEFT ASOF JOIN每个左侧 ts 找右侧近邻SELECTa.ts,a.current,b.standard_voltageFROMrealtime aLEFTASOFJOINreference bONa.tsb.tsANDa.locationb.location;-- 支持比较 -- 找 当前的最大者-- 找 当前的最小者-- 限制条件必须有时间比较LEFTASOFJOIN...ONa.tsb.ts[ANDtag_eq_conditions]-- 多列等值Tag 关联LEFTASOFJOINreference bONa.tsb.tsANDa.factoryb.factoryANDa.lineb.line;6. WINDOW JOIN时间窗口-- 找出每个事件前后窗口内的关联记录SELECTt.tsASevent_ts,h.tsASrelated_ts,t.value,h.valueFROMevents t WINDOWJOINhistory h WINDOW(1m)-- 窗口大小 ±30sONt.locationh.locationWHEREt.value100;-- 窗口语义-- 每个 t 的 ts 为中心[ts - window/2, ts window/2]-- 找出 h 中落在该窗口的所有行-- 一对多关系7. 子查询 JOIN-- 与聚合子查询 JOINSELECTm.ts,m.current,h.hist_avgFROMmeters mJOIN(SELECTtbname,AVG(current)AShist_avgFROMmetersWHEREtsnow-1dPARTITIONBYtbname)hONm.tbnameh.tbnameWHEREm.tsnow-1h;8. JOIN 性能限制注意 ① TDengine 推荐 JOIN 数量 ≤ 5 ② 时间窗口必须明确不能 ts 0 ③ 同 VGroup 子表 JOIN 最优 ④ 跨 VGroup 大表 JOIN 需 Shuffle慎用 高效 JOIN 模式 - 两侧都有时间过滤 - 两侧都有 Tag 过滤 - 时间和 Tag 条件配对 低效 JOIN - 无时间过滤的全表 JOIN - 多张超级表全字段 JOIN - JOIN 中含复杂表达式代码示例综合场景-- 同设备两类传感器对齐SELECTt.ts,t.currentASamperage,v.voltageASvoltage,t.current*v.voltageASpowerFROMcurrent_sensor tJOINvoltage_sensor vONt.tsv.tsANDt.device_idv.device_idWHEREt.tsnow-1h;-- 高频数据对齐低频参考SELECTm.ts,m.value,r.thresholdFROMminutely_data mLEFTASOFJOINreference_data rONm.tsr.tsANDm.device_typer.device_typeWHEREm.valuer.thresholdANDm.tsnow-1d;-- 事件前后关联SELECTa.tsASalarm_ts,m.tsASmeasure_ts,m.currentFROMalarm a WINDOWJOINmeters m WINDOW(5m)ONa.device_idm.tbnameWHEREa.severityCRITICALANDa.tsnow-1d;与子查询配合-- TOP N JOIN 详情SELECTtop.tbname,top.avg_c,m.ts,m.currentFROM(SELECTtbname,AVG(current)ASavg_cFROMmetersWHEREtsnow-1dPARTITIONBYtbnameORDERBYavg_cDESCLIMIT10)topJOINmeters mONtop.tbnamem.tbnameWHEREm.tsnow-1h;性能考量JOIN 性能影响因素影响双侧时间过滤决定扫描量Tag 过滤决定子表数JOIN 表数量复杂度指数级跨 VGroup需要 ShuffleASOF 的输入有序输入有序时 O(NM)优化建议建议原因限制时间范围关键列出具体列减少传输JOIN 不超过 3 表避免组合爆炸大表 小表用 INNER利于 Hash Join数据局部化避免 ShuffleFAQQ1: 为什么 JOIN 必须有时间条件时序数据按时间分布无时间条件的 JOIN 等同于笛卡尔积开销极大。强制时间条件防止误用。Q2: ASOF JOIN 性能如何输入按 ts 有序时时序天然如此用 Merge 风格 O(NM)。生产环境百万行毫秒~秒级。Q3: 一条 JOIN 能跨数据库吗支持跨数据库FROM db1.t1 JOIN db2.t2 ON ...。但跨集群 JOIN 不支持。Q4: JOIN 结果集很大如何处理加 LIMIT加更严格的过滤条件改用流计算预先 JOINQ5: JOIN 中的 NULL 处理NULL 不与 NULL 相等。Outer JOIN 中无匹配的列填 NULL。参考系统构架篇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 最佳实践》预聚合01-《TDengine RSMA》02-《TDengine TSMA — 时间维度的物化聚合视图》03-《TDengine SMA 内部实现》索引01-《TDengine Tag 索引》02-《TDengine SMA 索引》SQL 语句01-《TDengine DDL》02-《TDengine DML SELECT》03-《TDengine DML 函数完整参考》关于 TDengineTDengine 专为物联网IoT平台、工业大数据平台设计。其中TDengine TSDB 是一款高性能、分布式的时序数据库Time Series Database同时它还带有内建的缓存、流式计算、数据订阅等系统功能TDengine IDMP 是一款AI原生工业数据管理平台它通过树状层次结构建立数据目录对数据进行标准化、情景化并通过 AI 提供实时分析、可视化、事件管理与报警等功能。