
COLS 函数用户手册
函数概述
COLS 是 TDengine 中一个特殊的选择函数,用于在选择函数执行结果所在的数据行上,执行其他表达式并返回结果。该函数主要用于在一个 SQL 查询中获取多个选择函数结果及其关联列的场景。
版本支持:v3.3.6.0 及以上
语法
sql
COLS(func(expr), output_expr1 [, output_expr2, ...])
参数说明:
func(expr):必须是单行选择函数 (返回单行结果的选择函数),如FIRST、LAST、MIN、MAX等output_expr1, output_expr2, ...:在 func(expr) 结果所在行上执行的表达式,可以是列名、计算表达式等
返回值:
- 返回多列数据,每列数据类型为对应表达式返回结果的类型
- 注意:func(expr) 的结果本身不会输出
适用场景
1. 获取不同选择函数对应的时间戳
当需要同时获取多个聚合值(如最大值、最小值)及其各自对应的时间戳时,COLS 函数可以避免多次扫描数据。
2. 获取极值点的完整信息
在时序数据分析中,不仅需要知道最大值/最小值,还需要知道该极值点的其他维度信息(如位置、设备状态等)。
3. 多维度数据关联查询
在一次查询中获取多个不同统计维度的数据及其关联信息,提升查询效率。
使用限制
-
必须使用单行选择函数
- ✅ 支持:
FIRST、LAST、MIN、MAX、LAST_ROW等 - ❌ 不支持:
TOP、BOTTOM等多行选择函数
- ✅ 支持:
-
结果不包含选择函数值
- 如需同时输出选择函数的结果,需要额外添加该函数作为独立列
-
列别名规则
- 单列输出时:可对整个 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 语句简洁
- ✅ 执行效率高
注意事项
-
输出列命名
sql-- 单列输出 - 可对 COLS 设置别名 SELECT COLS(FIRST(ts), current) AS first_current FROM meters; -- 多列输出 - 对每列单独命名 SELECT COLS(FIRST(ts), current AS c, voltage AS v) FROM meters; -
与其他函数配合
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; -
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 提供实时分析、可视化、事件管理与报警等功能。