Clickhouse下采样到OHLC时间栏间隔

时间:2019-08-28 19:05:34

标签: group-by clickhouse yandex

对于表格,例如包含日期,价格时间序列以及每个价格,例如毫秒,如何将其降采样为具有时间间隔(例如时间间隔)的开放高低封闭(ohlc)行组分钟?

2 个答案:

答案 0 :(得分:3)

虽然带有数组的选项可以使用,但这里最简单的选项是将分组时间间隔与minmaxargMinargMax聚合函数结合使用。

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

答案 1 :(得分:2)

在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

诀窍是使用数组函数。解码通话的方法如下:

  1. groupArray将组内的列数据收集到一个数组中。
  2. arraySort使用时间戳顺序对值进行排序。我们使用lambda函数提供时间戳数组作为第一个值数组的排序键。
  3. arrayElement允许我们分别选择第一个和最后一个元素。

为了简化示例,我使用DateTime作为时间戳,该时间戳仅以1秒的间隔进行采样。您可以使用UInt64列来获取所需的任何精度。我在查询中添加了平均值以帮助检查结果。