如何在Apache IoTDB中获取对齐且填充后的最新值?
Apache IoTDB 2.0.5 多测点LAST查询结果不符合预期的解决方案
问题描述
使用树形模型的Apache IoTDB 2.0.5,查询同一设备下多个测点的最新值时,SELECT LAST语句返回多行不同时间戳的结果,无法将所有测点值对齐到最新时间戳并自动填充缺失值。
测试数据
同一设备root.factory.line1.device001下的三个测点数据:
INSERT INTO `root.factory.line1.device001`(timestamp, temperature) VALUES(1718445825000, 25.5); INSERT INTO `root.factory.line1.device001`(timestamp, humidity) VALUES(1718445852000, 65.0); INSERT INTO `root.factory.line1.device001`(timestamp, pressure) VALUES(1718445838000, 101.3);
错误尝试及结果
尝试的查询语句
SELECT LAST temperature, humidity, pressure FROM `root.factory.line1.device001`;
实际结果
返回3行不同时间戳的单测点数据:
+-----------------------------+----------------------------------------+-----+--------+ | `Time`| Timeseries|Value|DataType| +-----------------------------+----------------------------------------+-----+--------+ |2024-06-15T18:03:45.000+08:00|`root.factory.line1.device001.temperature`| 25.5| DOUBLE| |2024-06-15T18:04:12.000+08:00| `root.factory.line1.device001.humidity`| 65.0| DOUBLE| |2024-06-15T18:03:58.000+08:00| `root.factory.line1.device001.pressure`|101.3| DOUBLE| +-----------------------------+----------------------------------------+-----+--------+
期望结果
对齐到所有测点中最新的时间戳(2024-06-15T18:04:12.000+08:00),缺失的测点值用最近历史值填充,返回单行数据:
+-----------------------------+-------------+----------+---------+ | `Time`| temperature| humidity| pressure| +-----------------------------+-------------+----------+---------+ |2024-06-15T18:04:12.000+08:00| 25.5| 65.0| 101.3| +-----------------------------+-------------+----------+---------+
另一个失败的尝试
尝试用ORDER BY+LIMIT+FILL的方式,出现语法错误:
select * from `root.factory`.** order by `time` desc limit 1 fill(previous)
错误信息:
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 700: Error occurred while parsing SQL to physical plan: line 1:57 no viable alternative at input 'select * from `root.factory`.** order by `time` desc limit 1 fill'
正确的查询方案
方案1:子查询获取最大时间戳+填充
先获取设备下所有测点的最大时间戳,再基于该时间点查询并使用FILL(previous)填充缺失值:
SELECT temperature, humidity, pressure FROM `root.factory.line1.device001` WHERE time = (SELECT MAX(time) FROM `root.factory.line1.device001`) FILL(previous);
方案2:使用LATEST函数直接合并(IoTDB 2.0+支持)
利用LATEST函数直接获取各测点的最新值,并自动合并到同一行,时间戳统一为所有测点中的最大值:
SELECT LATEST(temperature), LATEST(humidity), LATEST(pressure) FROM `root.factory.line1.device001`;
错误尝试的原因分析
SELECT LAST在IoTDB中是针对每个测点单独返回其最新的时间戳和值,因此会生成多行结果,而非合并为单行。ORDER BY ... LIMIT 1与FILL的语法不兼容,IoTDB中FILL主要用于区间查询的缺失值填充,无法直接和LIMIT 1结合使用。
内容的提问来源于stack exchange,提问作者Yu Long
相关产品推荐
相关产品推荐

