您可以为此使用 continuous_aggregates。这是一个使用一些随机数据的完整示例:
CREATE TABLE "ticks" ("time" timestamp with time zone not null, "symbol" text, "price" decimal, "volume" float);
SELECT create_hypertable('ticks', 'time', chunk_time_interval => INTERVAL '1 day');
ALTER TABLE ticks SET (
timescaledb.compress,
timescaledb.compress_orderby = 'time',
timescaledb.compress_segmentby = 'symbol'
);
CREATE MATERIALIZED VIEW candlestick_1m
WITH (timescaledb.continuous) AS
SELECT time_bucket('1m', time),
"ticks"."symbol",
toolkit_experimental.candlestick_agg(time, price, volume) as candlestick
FROM "ticks"
GROUP BY 1, 2
ORDER BY 1
WITH NO DATA;
CREATE MATERIALIZED VIEW candlestick_1h
WITH (timescaledb.continuous) AS
SELECT time_bucket('1 hour', "time_bucket"),
symbol,
toolkit_experimental.rollup(candlestick) as candlestick
FROM "candlestick_1m"
GROUP BY 1, 2
WITH NO DATA;
CREATE MATERIALIZED VIEW candlestick_1d
WITH (timescaledb.continuous) AS
SELECT time_bucket('1 day', "time_bucket"),
symbol,
toolkit_experimental.rollup(candlestick) as candlestick
FROM "candlestick_1h"
GROUP BY 1, 2
WITH NO DATA;
INSERT INTO ticks
SELECT time, 'SYMBOL', 1 + (random()*30)::int, 100*(random()*10)::int
FROM generate_series(TIMESTAMP '2022-01-01 00:00:00',
TIMESTAMP '2022-02-01 00:01:00',
INTERVAL '15 min') AS time;
如果可以在较长的时间范围内使用 toolkit_experimental.rollup() 进行分组。
请注意,烛台对象需要通过每个属性的函数访问。
SELECT time_bucket,
symbol,
toolkit_experimental.open(candlestick),
toolkit_experimental.high(candlestick),
toolkit_experimental.low(candlestick),
toolkit_experimental.close(candlestick),
toolkit_experimental.volume(candlestick)
FROM candlestick_1d
WHERE time_bucket BETWEEN '2022-01-01' and '2022-01-07';
要构建 where 子句以仅按正确的日期进行过滤,您需要使用 extract(hour from...)。
例子:
select extract(hour from TIMESTAMP '2022-01-19 10:00');
┌─────────┐
│ extract │
├─────────┤
│ 10 │
└─────────┘
然后,对于您的情况,您可以在实体化视图中构建一个额外的 where 子句来组成这个所需的场景。