Apache IoTDB 2.0.4表模型中分组查询最大值及对应时间的SQL实现问题
Apache IoTDB 2.0.4表模型中分组查询最大值及对应时间的SQL实现问题
嗨,我来帮你搞定这个IoTDB的分组查询问题~
问题原因分析
你遇到的报错是因为IoTDB的SQL语法遵循标准SQL的分组查询规则:GROUP BY子句之外的列,要么被聚合函数包裹,要么必须出现在GROUP BY里。但如果把time加入GROUP BY,就会按metercode+time的组合分组,这显然不是你要的结果——你需要的是每个metercode下对应最大power的那条记录的时间,而不是按时间再拆分分组。
解决方案:用窗口函数实现
IoTDB 2.0及以上版本支持窗口函数,我们可以用ROW_NUMBER()窗口函数来标记每个metercode分组内的power排序,然后取排序第一的行(也就是power最大的那条记录)。
给你写好的完整SQL如下:
SELECT time, power, metercode FROM ( SELECT time, power, metercode, -- 按metercode分组,每组内按power降序排,最大power的行号为1 ROW_NUMBER() OVER (PARTITION BY metercode ORDER BY power DESC) AS rn FROM uemll WHERE metercode IN ('111','222') -- 注意:时间字符串要加单引号,这是更规范的写法 AND time >= '2023-06-02 00:00:00' AND time <= '2023-06-04 23:59:59' ) t -- 只保留每个分组内行号为1的记录(即power最大的那条) WHERE rn = 1;
查询结果
执行上面的SQL后,就能得到你期望的结果:
+-----------------------------+-----+---------+ | time |power|metercode| +-----------------------------+-----+---------+ |2023-06-02T00:00:02.000+08:00|200.0| 111 | |2023-06-02T00:00:04.000+08:00|300.0| 222 | +-----------------------------+-----+---------+
额外小提示
如果同一个metercode下有多个时间点的power是相同的最大值(比如111有两条记录power都是200),ROW_NUMBER()会随机返回其中一条。如果想把所有同最大值的记录都返回,可以把ROW_NUMBER()换成RANK(),这样相同最大值的行都会被标记为行号1,外层查询就能全部取出。




