TDengine 选择函数 LAST_ROW() 用户手册
LAST_ROW() 函数用户手册
函数定义
LAST_ROW(expr)
功能说明
LAST_ROW()
函数返回表/超级表的最后一条记录,即时间戳最大的那一行数据,包括可能为 NULL 的值。
版本要求
- 最低版本: v3.0.0.0
返回值
- 数据类型: 同应用的字段
- 返回内容: 时间戳最大的一行记录,可能包含 NULL 值
参数说明
参数 | 类型 | 说明 | 取值范围 |
---|---|---|---|
expr | 任意类型 | 要查询的字段表达式或 * | 所有字段类型 |
适用数据类型
- 所有字段类型: 支持所有数据类型,包括数值类型、字符串类型、时间戳类型等
适用范围
- 表类型: 表和超级表
- 查询支持: 支持聚合查询、窗口查询(INTERVAL)
- 多结果函数: 支持多列返回
与 LAST 函数的核心区别
特性 | LAST_ROW | LAST |
---|---|---|
NULL 值处理 | 返回包含 NULL 值的记录 | 忽略 NULL 值,只返回非 NULL 值 |
查询目标 | 最后一行记录(可能有 NULL) | 最后的非 NULL 值 |
INTERVAL 支持 | 支持 | 支持 |
应用场景 | 获取最新记录状态 | 获取最新有效数据 |
基本用法示例
单列查询
-- 获取最后一行的电流值(可能为 NULL)
SELECT LAST_ROW(current) FROM meters;-- 获取最后一行的电压值(可能为 NULL)
SELECT LAST_ROW(voltage) FROM meters;-- 获取最后一行的相位值(可能为 NULL)
SELECT LAST_ROW(phase) FROM meters;
多列查询
-- 获取最后一行的多个字段值
SELECT LAST_ROW(current), LAST_ROW(voltage), LAST_ROW(phase) FROM meters;-- 使用 LAST_ROW(*) 查询最后一行的所有列
SELECT LAST_ROW(*) FROM meters;
与 INTERVAL 配合使用
-- 每小时的最后一条记录
SELECT LAST_ROW(current) FROM meters INTERVAL(1h);-- 每天的最后一条记录
SELECT LAST_ROW(*) FROM meters INTERVAL(1d);-- 每30分钟的最后一条记录,按设备分组
SELECT LAST_ROW(current), LAST_ROW(voltage) FROM meters
INTERVAL(30m) GROUP BY tbname;
与 LAST 函数对比
-- 对比 LAST_ROW 和 LAST 的差异
SELECT LAST_ROW(current) as last_row_current, -- 最后一行的电流值(可能为NULL)LAST(current) as last_non_null_current -- 最后一个非NULL电流值
FROM meters;
智能电表场景应用示例
场景1:设备最新状态快照
-- 获取每个电表的最新记录状态
SELECT tbname,LAST_ROW(ts) as last_record_time,LAST_ROW(current) as current_status,LAST_ROW(voltage) as voltage_status,LAST_ROW(phase) as phase_status
FROM meters
GROUP BY tbname;
场景2:数据完整性检查
-- 检查各电表最新记录的数据完整性
SELECT tbname,LAST_ROW(ts) as last_time,CASE WHEN LAST_ROW(current) IS NULL THEN '电流传感器故障'WHEN LAST_ROW(voltage) IS NULL THEN '电压传感器故障'WHEN LAST_ROW(phase) IS NULL THEN '相位传感器故障'ELSE '传感器正常'END as sensor_status,LAST_ROW(current) as current_reading,LAST_ROW(voltage) as voltage_reading,LAST_ROW(phase) as phase_reading
FROM meters
GROUP BY tbname;
场景3:按时间窗口的最新记录
-- 查找每小时的最后一条记录
SELECT location,LAST_ROW(current) as hourly_last_current,LAST_ROW(voltage) as hourly_last_voltage,LAST_ROW(ts) as record_time
FROM meters
INTERVAL(1h) GROUP BY location;
场景4:设备健康状态评估
-- 综合评估设备健康状态
SELECT tbname,location,LAST_ROW(ts) as last_update,LAST_ROW(current) as current_reading,LAST_ROW(voltage) as voltage_reading,CASE WHEN LAST_ROW(ts) < NOW() - 1h THEN '设备离线'WHEN LAST_ROW(current) IS NULL AND LAST_ROW(voltage) IS NULL THEN '传感器全部故障'WHEN LAST_ROW(current) IS NULL THEN '电流传感器故障'WHEN LAST_ROW(voltage) IS NULL THEN '电压传感器故障'WHEN LAST_ROW(current) = 0 AND LAST_ROW(voltage) > 200 THEN '设备空载'ELSE '设备正常'END as device_health
FROM meters
GROUP BY tbname, location;
场景5:对比分析
-- 对比 LAST_ROW 和 LAST 的实际差异
SELECT tbname,location,LAST_ROW(current) as last_row_current,LAST_ROW(voltage) as last_row_voltage,LAST_ROW(ts) as last_row_time,LAST(current) as last_valid_current,LAST(voltage) as last_valid_voltage,LAST(ts) as last_valid_time,CASE WHEN LAST_ROW(current) IS NULL AND LAST(current) IS NOT NULL THEN '最新记录电流缺失'WHEN LAST_ROW(voltage) IS NULL AND LAST(voltage) IS NOT NULL THEN '最新记录电压缺失'ELSE '数据正常'END as data_quality_check
FROM meters
GROUP BY tbname, location
HAVING LAST_ROW(current) IS NULL OR LAST_ROW(voltage) IS NULL;
LAST_ROW(*) 的特殊用法
查询所有列的最后记录
-- 查询超级表最后一行的所有列
SELECT LAST_ROW(*) FROM meters;-- 按电表分组查询每个电表的最后记录
SELECT LAST_ROW(*) FROM meters GROUP BY tbname;-- 每小时的最后一行记录
SELECT LAST_ROW(*) FROM meters INTERVAL(1h);
标签列返回控制
-- 设置参数以包含标签列
SET multiResultFunctionStarReturnTags=1;
SELECT LAST_ROW(*) FROM meters;-- 恢复默认设置
SET multiResultFunctionStarReturnTags=0;
特殊情况说明
NULL 值处理
-- LAST_ROW 会保留 NULL 值
SELECT LAST_ROW(current) as may_be_null, -- 可能为 NULLLAST(current) as never_null -- 不会为 NULL(除非所有值都是 NULL)
FROM meters;-- 处理可能的 NULL 值,使用 CASE 语句替代不支持的 COALESCE
SELECT tbname,CASE WHEN LAST_ROW(current) IS NULL THEN 0 ELSE LAST_ROW(current) END as safe_current,CASE WHEN LAST_ROW(voltage) IS NULL THEN 220 ELSE LAST_ROW(voltage) END as safe_voltage
FROM meters
GROUP BY tbname;
时间戳相同的记录
当多行记录有相同的最大时间戳时,LAST_ROW 会随机返回其中一行。
复合主键处理
对于有复合主键的表,相同时间戳的记录会按主键排序选择。
性能优化
缓存配置
-- 为频繁的 LAST_ROW 查询启用缓存
ALTER DATABASE test CACHEMODEL 'last_row';-- 或者同时启用 LAST 和 LAST_ROW 缓存
ALTER DATABASE test CACHEMODEL 'both';
查询优化
-- 合理使用时间范围过滤提高性能
SELECT LAST_ROW(current) FROM meters
WHERE ts >= NOW() - 1d
GROUP BY tbname;
注意事项
- NULL 值保留: LAST_ROW 返回最后一行的实际值,包括 NULL
- 时间戳依赖: 依赖时间戳确定"最后一行"
- 随机性: 相同最大时间戳的多条记录会随机选择一条
- INTERVAL 支持: 支持与窗口查询(INTERVAL)一起使用
- 性能考虑: 在大表上使用时建议配合时间范围过滤
- 时间语法: 使用 TDengine 支持的时间间隔语法(如
NOW() - 1h
) - NULL 值处理: 使用 CASE 语句处理 NULL 值,TDengine 不支持 COALESCE 函数
相关函数
LAST()
: 返回最后的非 NULL 值FIRST()
: 返回最先的非 NULL 值TOP()
: 返回最大的 k 个值BOTTOM()
: 返回最小的 k 个值TAIL()
: 返回最后 k 行记录
感谢您的提醒!我已经将所有的 COALESCE 函数替换为 CASE 语句,这是 TDengine 支持的正确语法。
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。