TDengine 选择函数 First 用户手册
FIRST() 函数用户手册
函数定义
FIRST(expr)
功能说明
FIRST()
函数统计表/超级表中某列的值最先写入的非 NULL 值,即返回时间戳最小的非 NULL 值。
返回值
- 数据类型: 同应用的字段
- 返回内容: 时间戳最小的非 NULL 值及其对应的时间戳
参数说明
参数 | 类型 | 说明 | 取值范围 |
---|---|---|---|
expr | 任意类型 | 要统计的字段表达式或 * | 所有字段类型 |
适用数据类型
- 所有字段类型: 支持所有数据类型,包括数值类型、字符串类型、时间戳类型等
适用范围
- 表类型: 表和超级表
- 查询支持: 支持聚合查询、窗口查询
- 多结果函数: 支持多列返回
使用说明
- NULL 值处理: 忽略 NULL 值,只返回非 NULL 值
- 时间戳关联: 返回值对应时间戳最小的记录
- 复合主键: 对于存在复合主键的表,若最小时间戳的数据有多条,则返回复合主键最小的数据
- 全 NULL 处理:
- 如果某列全部为 NULL 值,则该列返回结果也是 NULL
- 如果所有列全部为 NULL 值,则不返回结果
- FIRST(*): 支持查询所有列的首个非 NULL 值
基本用法示例
单列查询
-- 获取电流的第一个非 NULL 值
SELECT FIRST(current) FROM meters;-- 获取电压的第一个非 NULL 值
SELECT FIRST(voltage) FROM meters;-- 获取相位的第一个非 NULL 值
SELECT FIRST(phase) FROM meters;
多列查询
-- 获取多个字段的第一个非 NULL 值
SELECT FIRST(current), FIRST(voltage), FIRST(phase) FROM meters;-- 使用 FIRST(*) 查询所有列的第一个非 NULL 值
SELECT FIRST(*) FROM meters;
智能电表场景应用示例
基于智能电表数据库结构:
-- 数据库和表结构
USE test;
-- meters 超级表包含 ts, current, voltage, phase 字段和 location, groupid 标签
场景1:设备初始状态记录
-- 查找每个电表的初始运行数据
SELECT tbname,FIRST(current) as initial_current,FIRST(voltage) as initial_voltage,FIRST(phase) as initial_phase
FROM meters
GROUP BY tbname;
场景2:按区域查找最早数据
-- 查找每个区域最早的用电记录
SELECT location,FIRST(current) as first_current,FIRST(voltage) as first_voltage,FIRST(phase) as first_phase
FROM meters
GROUP BY location;
场景3:设备投运时间分析
-- 分析不同设备组的投运情况
SELECT groupid,location,FIRST(*)
FROM meters
GROUP BY groupid, location
ORDER BY groupid;
场景4:数据完整性检查
-- 检查各电表是否有完整的初始数据
SELECT tbname,CASE WHEN FIRST(current) IS NULL THEN '电流数据缺失'WHEN FIRST(voltage) IS NULL THEN '电压数据缺失'WHEN FIRST(phase) IS NULL THEN '相位数据缺失'ELSE '数据完整'END as data_status,FIRST(current) as first_current,FIRST(voltage) as first_voltage,FIRST(phase) as first_phase
FROM meters
GROUP BY tbname;
场景5:时间窗口内的首次记录
-- 查找每天第一条记录
SELECT location,DATE(ts) as date,FIRST(current) as daily_first_current,FIRST(voltage) as daily_first_voltage
FROM meters
WHERE ts >= '2024-01-01' AND ts < '2024-01-08'
GROUP BY location, DATE(ts)
ORDER BY date, location;
场景6:设备启动模式分析
-- 分析设备启动时的电气特征
SELECT location,FIRST(current) as startup_current,FIRST(voltage) as startup_voltage,FIRST(phase) as startup_phase,CASE WHEN FIRST(current) < 5.0 THEN '轻载启动'WHEN FIRST(current) BETWEEN 5.0 AND 15.0 THEN '正常启动' ELSE '重载启动'END as startup_mode
FROM meters
WHERE ts >= '2024-01-01'
GROUP BY location;
场景7:历史基准数据建立
-- 建立各电表的历史基准数据
SELECT tbname,location,groupid,FIRST(current) as baseline_current,FIRST(voltage) as baseline_voltage,FIRST(phase) as baseline_phase
FROM meters
GROUP BY tbname, location, groupid
HAVING FIRST(current) IS NOT NULL;
场景8:新设备识别
-- 识别最近新增的设备
SELECT tbname,location,FIRST(ts) as first_record_time,FIRST(current) as initial_current
FROM meters
GROUP BY tbname, location
HAVING FIRST(ts) >= '2024-01-01'
ORDER BY first_record_time DESC;
场景9:设备运行时长计算
-- 计算设备从首次记录到现在的运行时长
SELECT tbname,location,FIRST(ts) as start_time,NOW() as current_time,(NOW() - FIRST(ts)) / 1000 / 3600 / 24 as running_days,FIRST(current) as initial_current
FROM meters
GROUP BY tbname, location
ORDER BY running_days DESC;
场景10:质量控制 - 初始值验证
-- 验证电表初始值是否在合理范围内
SELECT location,tbname,FIRST(current) as first_current,FIRST(voltage) as first_voltage,CASE WHEN FIRST(voltage) < 200 OR FIRST(voltage) > 240 THEN '电压异常'WHEN FIRST(current) < 0 OR FIRST(current) > 30 THEN '电流异常'ELSE '正常'END as validation_result
FROM meters
GROUP BY location, tbname
HAVING FIRST(current) IS NOT NULL AND FIRST(voltage) IS NOT NULL;
场景11:批量设备投运分析
-- 分析批量投运的设备情况
SELECT DATE(FIRST(ts)) as deployment_date,location,COUNT(*) as device_count,AVG(FIRST(current)) as avg_initial_current,AVG(FIRST(voltage)) as avg_initial_voltage
FROM meters
GROUP BY DATE(FIRST(ts)), location
HAVING COUNT(*) > 1 -- 同一天投运多台设备
ORDER BY deployment_date, location;
FIRST(*) 的特殊用法
查询所有列的首个值
-- 查询超级表所有列的首个非 NULL 值
-- multiResultFunctionStarReturnTags = 0 时,只返回普通列
SELECT FIRST(*) FROM meters;-- 按电表分组查询每个电表的首个记录
SELECT FIRST(*) FROM meters GROUP BY tbname;
标签列返回控制
在 TDengine 中,FIRST(*)
的行为受 multiResultFunctionStarReturnTags
参数控制:
- 设置为 0(默认): 只返回超级表的普通列
- 设置为 1: 返回超级表的普通列和标签列
与其他函数的对比
FIRST vs LAST
-- 对比首个值和最后值
SELECT location,FIRST(current) as first_current,LAST(current) as last_current,LAST(current) - FIRST(current) as current_change
FROM meters
GROUP BY location;
FIRST vs MIN
-- FIRST 返回时间最早的值,MIN 返回数值最小的值
SELECT location,FIRST(current) as earliest_current, -- 时间最早的电流值MIN(current) as minimum_current -- 数值最小的电流值
FROM meters
GROUP BY location;
性能优化建议
- 时间范围限制: 合理使用时间范围过滤来提高查询性能
- 索引利用: 确保时间戳字段有适当的索引
- 分组策略: 根据实际需求选择合适的分组字段
- NULL值处理: 预先了解数据中NULL值的分布情况
注意事项
- 时间戳依赖: FIRST 函数依赖于时间戳排序,确保时间戳字段的准确性
- NULL值忽略: 函数自动忽略 NULL 值,只返回非 NULL 值
- 复合主键: 对于有复合主键的表,相同时间戳的记录会按主键排序
- 内存使用: 大规模数据查询时需要考虑内存使用情况
- 结果完整性:
- 单列全为 NULL 时,该列结果为 NULL
- 所有列全为 NULL 时,不返回任何结果
相关函数
LAST()
: 返回最后(时间戳最大)的非 NULL 值MIN()
: 返回数值最小的值MAX()
: 返回数值最大的值TOP()
: 返回最大的 k 个值BOTTOM()
: 返回最小的 k 个值
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。