使用 QuestDB 获取采样数据之前 5 行的运行最小值

问题描述 投票:0回答:1

我有一个 QuestDB 表,每秒都会收到一些记录。我以 1 分钟为间隔进行聚合,如

select timestamp, symbol, avg(price) as price from trades 
where timestamp in yesterday() and side='buy' sample by 1m 

现在我想获取每个采样行在过去 5 分钟内具有相同符号的行的最小值。

我尝试使用窗口函数,但 QuestDB 尚不支持

min
函数作为窗口函数。否则我可以做类似的事情:

select timestamp, symbol, avg(price) as price,
min(avg(price)) over (partition by symbol range 5 minutes preceding) as min_price from trades 
where timestamp in yesterday() and side='buy' sample by 1m 

有没有解决方法,或者我需要实现客户端吗?

sql database time-series questdb
1个回答
0
投票

在撰写本文时,

min
函数是通过github问题请求的函数之一,所以也许它会在某个时候实现。与此同时,我能想到一个解决方法。请注意,该解决方法并不完美,但它可能适用于某些用例。步骤是:

  • 与原始查询一样,按 1m 采样,但使用 FILL(null),因此我们得到了密集的结果,其中每分钟我们为每个不同的符号精确获取 1 行。
  • 对采样的行进行编号,所以现在我可以将位置除以 5,并将在 5 分钟块内对行进行分类
  • 现在我们可以使用窗口函数按价格排序,并按交易品种和 5 分钟块进行分区,因此每 5 分钟我们都会得到最小值。

请注意,使用此解决方案,每一行都会分配给一个 5 分钟的块,并且为每个块找到最小值,这不是真正的移动最小值,因为它没有考虑我之前的五行,而是考虑了同一 5 分钟块内的行。如果这适合您的用例,那就完美了,否则可能还有其他更合适的解决方案。

我的sql尝试解决这个问题是:

with sampled as 
(
select timestamp, symbol, avg(price) as price from trades 
where timestamp in yesterday() and side='buy' and symbol = 'BTC-USDT' sample by 1m fill(null) 
), numbered AS (
select *, row_number over(partition by symbol) as pos from sampled
), grouped_by_interval AS (
select timestamp, symbol, price, pos, pos / 5 as modulo
from numbered
)
select timestamp, symbol, pos, modulo, price , first_value(price) over(partition by symbol, modulo order by price asc) as min_price_5_mins
from grouped_by_interval;
© www.soinside.com 2019 - 2024. All rights reserved.