TDengine COLS 函数用户手册

COLS 函数用户手册

函数概述

COLS 是 TDengine 中一个特殊的选择函数,用于在选择函数执行结果所在的数据行上,执行其他表达式并返回结果。该函数主要用于在一个 SQL 查询中获取多个选择函数结果及其关联列的场景。

版本支持:v3.3.6.0 及以上

语法

sql 复制代码
COLS(func(expr), output_expr1 [, output_expr2, ...])

参数说明

  • func(expr):必须是单行选择函数 (返回单行结果的选择函数),如 FIRSTLASTMINMAX
  • output_expr1, output_expr2, ...:在 func(expr) 结果所在行上执行的表达式,可以是列名、计算表达式等

返回值

  • 返回多列数据,每列数据类型为对应表达式返回结果的类型
  • 注意:func(expr) 的结果本身不会输出

适用场景

1. 获取不同选择函数对应的时间戳

当需要同时获取多个聚合值(如最大值、最小值)及其各自对应的时间戳时,COLS 函数可以避免多次扫描数据。

2. 获取极值点的完整信息

在时序数据分析中,不仅需要知道最大值/最小值,还需要知道该极值点的其他维度信息(如位置、设备状态等)。

3. 多维度数据关联查询

在一次查询中获取多个不同统计维度的数据及其关联信息,提升查询效率。

使用限制

  1. 必须使用单行选择函数

    • ✅ 支持:FIRSTLASTMINMAXLAST_ROW
    • ❌ 不支持:TOPBOTTOM 等多行选择函数
  2. 结果不包含选择函数值

    • 如需同时输出选择函数的结果,需要额外添加该函数作为独立列
  3. 列别名规则

    • 单列输出时:可对整个 COLS 函数设置别名
    • 多列输出时:可对 COLS 函数内的每个输出列分别设置别名

智能电表示例

场景说明

假设有智能电表数据表 meters,包含以下字段:

  • ts:时间戳(主键)
  • current:电流值
  • voltage:电压值
  • phase:相位
  • location:位置信息(标签)
  • groupid:分组ID(标签)

示例 1:获取最大/最小电流对应的不同时间戳

需求:查询每个电表在指定时间段内,最大电流和最小电流分别发生的时间。

sql 复制代码
SELECT 
    tbname,
    COLS(MAX(current), ts) AS max_current_time,
    COLS(MIN(current), ts) AS min_current_time
FROM meters
WHERE ts >= '2024-01-01 00:00:00' AND ts < '2024-01-02 00:00:00'
PARTITION BY tbname;

结果示例

复制代码
tbname          | max_current_time        | min_current_time
----------------|-------------------------|-------------------------
d1001           | 2024-01-01 14:23:45.000 | 2024-01-01 03:15:22.000
d1002           | 2024-01-01 16:48:33.000 | 2024-01-01 02:05:18.000

说明:这个查询一次扫描就能获取最大电流和最小电流各自对应的时间戳,如果不使用 COLS,需要编写复杂的子查询或多次扫描数据。

示例 2:获取极值点的多维信息

需求:查询最大电流时刻的电压和相位信息。

sql 复制代码
SELECT 
    tbname,
    MAX(current) AS max_current,
    COLS(MAX(current), ts, voltage, phase) AS (max_ts, max_voltage, max_phase)
FROM meters
WHERE ts >= '2024-01-01 00:00:00' AND ts < '2024-01-02 00:00:00'
PARTITION BY tbname;

结果示例

复制代码
tbname | max_current | max_ts                  | max_voltage | max_phase
-------|-------------|-------------------------|-------------|----------
d1001  | 12.5        | 2024-01-01 14:23:45.000 | 220.3       | 0.95
d1002  | 11.8        | 2024-01-01 16:48:33.000 | 218.7       | 0.92

示例 3:同时获取首末值的完整信息

需求:获取每个电表每小时第一条和最后一条记录的时间戳和电流值。

sql 复制代码
SELECT 
    _wstart AS window_start,
    tbname,
    COLS(FIRST(current), ts) AS (first_ts, first_current),
    COLS(LAST(current), ts) AS (last_ts, last_current)
FROM meters
WHERE ts >= '2024-01-01 00:00:00' AND ts < '2024-01-02 00:00:00'
PARTITION BY tbname
INTERVAL(1h);

结果示例

复制代码
window_start            | tbname | first_ts                | first_current | last_ts                 | last_current
------------------------|--------|-------------------------|---------------|-------------------------|-------------
2024-01-01 00:00:00.000 | d1001  | 2024-01-01 00:00:05.000 | 10.2         | 2024-01-01 00:59:58.000 | 10.8
2024-01-01 01:00:00.000 | d1001  | 2024-01-01 01:00:03.000 | 10.5         | 2024-01-01 01:59:55.000 | 11.2

示例 4:复杂表达式计算

需求:计算最大功率时刻的功率值(电流×电压)。

sql 复制代码
SELECT 
    tbname,
    COLS(MAX(current * voltage), ts, current, voltage, current * voltage) AS 
        (max_power_ts, max_current, max_voltage, max_power)
FROM meters
WHERE ts >= '2024-01-01 00:00:00' AND ts < '2024-01-02 00:00:00'
PARTITION BY tbname;

性能优势

传统方式(不使用 COLS)

sql 复制代码
-- 需要两次子查询
SELECT 
    t1.tbname,
    t1.max_current_time,
    t2.min_current_time
FROM (
    SELECT tbname, ts AS max_current_time
    FROM meters
    WHERE (tbname, current) IN (
        SELECT tbname, MAX(current)
        FROM meters
        WHERE ts >= '2024-01-01' AND ts < '2024-01-02'
        GROUP BY tbname
    )
) t1
JOIN (
    SELECT tbname, ts AS min_current_time
    FROM meters
    WHERE (tbname, current) IN (
        SELECT tbname, MIN(current)
        FROM meters
        WHERE ts >= '2024-01-01' AND ts < '2024-01-02'
        GROUP BY tbname
    )
) t2 ON t1.tbname = t2.tbname;

问题

  • 需要多次数据扫描
  • SQL 语句复杂
  • 执行效率低

使用 COLS 函数

sql 复制代码
SELECT 
    tbname,
    COLS(MAX(current), ts) AS max_current_time,
    COLS(MIN(current), ts) AS min_current_time
FROM meters
WHERE ts >= '2024-01-01' AND ts < '2024-01-02'
PARTITION BY tbname;

优势

  • ✅ 一次数据扫描
  • ✅ SQL 语句简洁
  • ✅ 执行效率高

注意事项

  1. 输出列命名

    sql 复制代码
    -- 单列输出 - 可对 COLS 设置别名
    SELECT COLS(FIRST(ts), current) AS first_current FROM meters;
    
    -- 多列输出 - 对每列单独命名
    SELECT COLS(FIRST(ts), current AS c, voltage AS v) FROM meters;
  2. 与其他函数配合

    sql 复制代码
    -- 可以同时使用多个 COLS
    SELECT 
        MAX(current) AS max_val,
        COLS(MAX(current), ts) AS max_ts,
        MIN(current) AS min_val,
        COLS(MIN(current), ts) AS min_ts
    FROM meters;
  3. NULL 值处理

    • 如果选择函数结果为 NULL,COLS 返回的所有列也为 NULL

相关函数

  • FIRST:返回第一条记录的值
  • LAST:返回最后一条记录的值
  • MIN:返回最小值
  • MAX:返回最大值
  • LAST_ROW:返回最新一条记录

总结

COLS 函数是 TDengine 为时序数据查询场景专门设计的高效函数,特别适合:

  • 需要获取聚合值对应的时间戳或其他维度信息的场景
  • 需要在一次查询中关联多个选择函数结果的场景
  • 需要提升复杂关联查询性能的场景

通过合理使用 COLS 函数,可以显著简化 SQL 语句,提升查询性能。

关于 TDengine

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

相关推荐
yddddddy1 小时前
Django在项目中的作用
数据库·python·django
老蒋新思维1 小时前
创客匠人 2025 峰会启示:AI 重构知识变现,从内容输出到资产运营
大数据·人工智能·tcp/ip·重构·创始人ip·创客匠人·知识变现
嘉禾望岗5031 小时前
spark standalone模式HA部署,任务失败重提测试
大数据·分布式·spark
Dxy12393102161 小时前
Elasticsearch数据更新简介
大数据·elasticsearch·搜索引擎
B站计算机毕业设计之家1 小时前
电商数据实战:python京东商品爬取与可视化系统 大数据 Hadoop spark 优秀项目(源码)✅
大数据·hadoop·python·机器学习·spark·echarts·推荐算法
q***31141 小时前
使用 Qt 插件和 SQLCipher 实现 SQLite 数据库加密与解密
数据库·qt·sqlite
x***44011 小时前
远程访问mysql数据库的正确打开方式
数据库·mysql
AAAAA92401 小时前
蜂窝物联网模组中的GPS+北斗双模定位技术
物联网·位置
p***43481 小时前
后端在消息系统中的顺序保证
数据库·数据仓库·docker