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 提供实时分析、可视化、事件管理与报警等功能。

相关推荐
专业开发者6 分钟前
艾通科技(ITON Technology)借助蓝牙 ® 网状网络,构建适用于自动化控制应用的大规模设备网络
运维·物联网·自动化
湘-枫叶情缘7 分钟前
“智律提效”AI数字化运营落地项目可行性方案
大数据·人工智能·产品运营
gjc59230 分钟前
MySQL 主从复制全解析:从基础原理到高级实战简介(附架构图)
数据库·mysql
kong790692836 分钟前
MySQL的安装与卸载
数据库·mysql
JIngJaneIL39 分钟前
基于java+ vue办公管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
tq108641 分钟前
回到原点再出发2
数据库
minhuan1 小时前
大模型应用:与传统数据库融合:打造关系型数据库MySQL的向量检索能力.31
数据库·mysql·mysql的向量检索·向量模型应用
向往着的青绿色1 小时前
编程式事务,更加精细化的控制
java·开发语言·数据库·spring·性能优化·个人开发·设计规范
是喵斯特ya1 小时前
数据库的权限提升
数据库·安全
玩转数据库管理工具FOR DBLENS1 小时前
企业数据架构选型指南:关系型与非关系型数据库的实战抉择
数据库·测试工具·mysql·oracle·架构·nosql