【发布时间】:2020-01-02 01:13:30
【问题描述】:
对于一个表,例如包含日期,价格时间序列,每个价格例如毫秒,如何将其下采样为具有时间间隔的开高低收 (ohlc) 行组,例如分钟?
【问题讨论】:
标签: group-by clickhouse yandex
对于一个表,例如包含日期,价格时间序列,每个价格例如毫秒,如何将其下采样为具有时间间隔的开高低收 (ohlc) 行组,例如分钟?
【问题讨论】:
标签: group-by clickhouse yandex
虽然带有数组的选项可以工作,但这里最简单的选项是使用按时间间隔分组的组合与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
【讨论】:
在 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
诀窍是使用数组函数。以下是解码调用的方法:
为了使示例简单,我使用 DateTime 作为时间戳,它仅以 1 秒的间隔进行采样。您可以使用 UInt64 列来获得所需的任何精度。我在查询中添加了一个平均值以帮助检查结果。
【讨论】: