点击下采样到ohlc时间条间隔

aij0ehis  于 2021-07-15  发布在  ClickHouse
关注(0)|答案(2)|浏览(514)

对于一个表,例如包含一个日期、价格、时间序列和每毫秒一次的价格,如何按时间间隔(例如分钟)将其下采样到一组开盘-高-低-收盘(ohlc)行中?

dba5bblo

dba5bblo1#

虽然使用数组的选项可以工作,但这里最简单的选项是使用group-by-timeinterval和 min , max , argMin , argMax 聚合函数。

SELECT 
  id,
  minute,
  max(value) AS high,
  min(value) AS low,
  avg(value) AS avg,
  argMin(value, timestamp) AS first,
  argMax(value, timestamp) AS last
FROM security
GROUP BY id, toStartOfMinute(timestamp) AS minute
ORDER BY minute
xghobddn

xghobddn2#

在clickhouse中,您可以用数组解决这类问题。我们假设一个如下表:

CREATE TABLE security (
  timestamp DateTime,
  id UInt32,
  value Float32
)
ENGINE=MergeTree
PARTITION BY toYYYYMM(timestamp)
ORDER BY (id, timestamp)

您可以使用如下查询将采样间隔减少到一分钟:

SELECT 
  id, minute, max(value) AS high, min(value) AS low, avg(value) AS avg,
  arrayElement(arraySort((x,y)->y, 
    groupArray(value), groupArray(timestamp)), 1) AS first,
  arrayElement(arraySort((x,y)->y, 
    groupArray(value), groupArray(timestamp)), -1) AS last
FROM security
GROUP BY id, toStartOfMinute(timestamp) AS minute
ORDER BY minute

诀窍是使用数组函数。以下是如何解码通话:
grouparray将组中的列数据收集到一个数组中。
arraysort使用时间戳顺序对值进行排序。我们使用lambda函数提供时间戳数组作为第一个值数组的排序键。
arrayelement允许我们分别选择第一个和最后一个元素。
为了保持示例的简单性,我使用datetime作为时间戳,它只以1秒的间隔采样。可以使用uint64列来获得所需的任何精度。我在查询中添加了一个平均值来帮助检查结果。

相关问题