You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Apache IoTDB HOP滑动窗口单条数据重复入多窗口的过滤方案咨询

Apache IoTDB HOP窗口过滤稀疏边缘窗口问题

问题背景

在Apache IoTDB 2.0.8中使用HOP表函数对股票报价数据执行滑动窗口聚合时,由于窗口步长(SLIDE)小于窗口大小(SIZE)导致窗口重叠,单条原始数据会被分配到多个窗口中。部分边缘窗口仅包含单条原始数据,导致相同聚合结果重复输出,造成下游统计数据膨胀。

最小可复现数据

CREATE TABLE stock_bid(
  `time` TIMESTAMP `TIME`,
  stock_id STRING TAG,
  price FLOAT FIELD
);

INSERT INTO stock_bid(`time`, stock_id, price) VALUES
('2021-01-01T09:05:00', 'AAPL', 100.0),
('2021-01-01T09:06:00', 'TESL', 200.0),
('2021-01-01T09:07:00', 'AAPL', 103.0),
('2021-01-01T09:07:00', 'TESL', 202.0),
('2021-01-01T09:09:00', 'AAPL', 102.0),
('2021-01-01T09:15:00', 'TESL', 195.0);

原始查询语句

SELECT window_start, window_end, stock_id, avg(price) AS avg_price
FROM HOP(DATA => stock_bid, TIMECOL => '`time`', SLIDE => 5m, SIZE => 10m)
GROUP BY window_start, window_end, stock_id;

实际结果

+-----------------------------+-----------------------------+--------+------------------+
| window_start| window_end|stock_id| avg_price|
+-----------------------------+-----------------------------+--------+------------------+
|2021-01-01T09:00:00.000+08:00|2021-01-01T09:10:00.000+08:00| TESL| 201.0|
|2021-01-01T09:05:00.000+08:00|2021-01-01T09:15:00.000+08:00| TESL| 201.0|
|2021-01-01T09:10:00.000+08:00|2021-01-01T09:20:00.000+08:00| TESL| 195.0|
|2021-01-01T09:15:00.000+08:00|2021-01-01T09:25:00.000+08:00| TESL| 195.0|
|2021-01-01T09:00:00.000+08:00|2021-01-01T09:10:00.000+08:00| AAPL|101.66666666666667|
|2021-01-01T09:05:00.000+08:00|2021-01-01T09:15:00.000+08:00| AAPL|101.66666666666667|
+-----------------------------+-----------------------------+--------+------------------+
Total line number = 6

问题说明

09:15:00的TESL数据(价格195.0)同时落入09:10~09:2009:15~09:25两个窗口,且每个窗口仅包含该条数据,导致相同聚合结果重复输出,单条原始数据被统计两次。需要保留包含至少2条原始数据的窗口,丢弃仅含单条数据的边缘窗口。

期望输出

| window_start           | window_end             | stock_id | avg_price         | row_count |
|------------------------|------------------------|----------|-------------------|-----------|
|2021-01-01T09:00:00+0800|2021-01-01T09:10:00+0800| TESL     | 201.0             | 2         |
|2021-01-01T09:05:00+0800|2021-01-01T09:15:00+0800| TESL     | 201.0             | 2         |
|2021-01-01T09:00:00+0800|2021-01-01T09:10:00+0800| AAPL     |101.66666666666667 | 3         |
|2021-01-01T09:05:00+0800|2021-01-01T09:15:00+0800| AAPL     |101.66666666666667 | 3         |

解答

1. HOP函数是否支持MIN_ROWS参数?

Apache IoTDB 2.0.8版本的HOP表函数不支持MIN_ROWS这类内置参数,无法直接通过窗口配置过滤稀疏窗口。

2. 过滤稀疏边缘窗口的惯用方法

最简洁高效的方法是使用HAVING子句配合COUNT(*)聚合函数,直接过滤掉数据行数不足的窗口:

SELECT 
  window_start, 
  window_end, 
  stock_id, 
  avg(price) AS avg_price,
  COUNT(*) AS row_count
FROM HOP(DATA => stock_bid, TIMECOL => '`time`', SLIDE => 5m, SIZE => 10m)
GROUP BY window_start, window_end, stock_id
HAVING COUNT(*) >= 2;

逻辑说明:

  • COUNT(*)统计每个窗口内的原始数据行数
  • HAVING COUNT(*) >= 2直接过滤掉仅包含1条或0条数据的窗口,完美匹配需求,得到期望输出

其他可选方法对比

  • 子查询方式:先通过HOP聚合得到所有窗口结果,再在外层查询中过滤行数>=2的记录,逻辑和HAVING一致,但写法更繁琐,性能无优势。
  • 切换为TUMBLE窗口:虽然能避免窗口重叠导致的重复输出,但会丢失滑动窗口的连续统计特性,仅适用于业务允许放弃滑动聚合逻辑的场景,不推荐作为此类问题的解决方案。

内容的提问来源于stack exchange,提问作者Alex Zhou

火山引擎 最新活动