InfluxDB技术问题:如何按分钟级计算差值的求和结果
解决InfluxDB中
non_negative_difference配合外层分组求和的报错问题 问题分析
你遇到的错误aggregate function required inside the call to non_negative_difference,本质是InfluxDB的查询规划器优化逻辑导致的:当你在外层使用GROUP BY time(1m)时,数据库会尝试把这个分组逻辑下推到子查询中,让non_negative_difference在每个1分钟的分组内执行。但每个分钟分组内的连续数据点可能不足(甚至只有一个点),无法计算连续值的差值,因此数据库要求你在non_negative_difference内部使用聚合函数(比如last()、sum())——但这显然不符合你的需求:你需要先计算整个时间序列中每个连续点的差值,再按分钟对这些差值求和。
而单独执行子查询时,没有外层分组的干扰,non_negative_difference是在完整的原始数据序列上计算连续差值,所以可以正常返回结果。
解决方案
我们需要让子查询先完整计算所有连续点的差值,再在外层进行分钟级求和。可以通过嵌套子查询的方式,强制数据库先执行原始数据的序列差值计算,再处理分组:
SELECT sum(ph1), sum(ph2), sum(ph3) FROM ( -- 内层子查询:确保先获取完整的原始数据并按时间排序 SELECT non_negative_difference(day_chan1) AS ph1, non_negative_difference(day_chan2) AS ph2, non_negative_difference(day_chan3) AS ph3 FROM ( SELECT time, day_chan1, day_chan2, day_chan3 FROM electricity ORDER BY time ASC ) ) GROUP BY time(1m) tz('Europe/Dublin')
另一种等价写法(针对有固定时间粒度的原始数据)
如果你的原始数据是按固定时间间隔采集的(比如每秒一个点),也可以先按原始粒度分组保留每个时间点的数值,再计算差值,最后分钟求和:
SELECT sum(ph1), sum(ph2), sum(ph3) FROM ( SELECT non_negative_difference(last(day_chan1)) AS ph1, non_negative_difference(last(day_chan2)) AS ph2, non_negative_difference(last(day_chan3)) AS ph3 FROM electricity GROUP BY time(1s) -- 匹配你的原始数据时间精度 ) GROUP BY time(1m) tz('Europe/Dublin')
验证结果
执行上述查询后,会先得到子查询中所有连续点的差值(和你单独执行子查询的结果一致),再按分钟对ph1、ph2、ph3分别求和,最终得到你期望的结果:
time ph1 ph2 ph3 ---- --- --- --- 2017-04-02T14:40:00Z 0 0 2 2017-04-02T14:41:00Z 1 1 3 2017-04-02T14:42:00Z 1 2 3
内容的提问来源于stack exchange,提问作者Bazinga777
相关产品推荐
相关产品推荐

