postgres/timescaledb 中的连续聚合需要 time_bucket-function?

And*_*nfo 3 postgresql timescaledb

我有一个 SELECT 查询,它给我一些东西的聚合总和(每小时使用分钟数)。按 ID、工作日和观察时间分组。

SELECT id,
       extract(dow from observed_date) AS weekday, (  --observed_date  is type date
       observed_hour,  -- is type timestamp without timezone, every full hour 00:00:00, 01:00:00, ...
       sum(minutes_per_hour_used)
FROM base_table
GROUP BY id, weekday, observed_hour
ORDER BY id, weekday, observed_hour;
Run Code Online (Sandbox Code Playgroud)

结果看起来不错,但现在我想将其存储在自我维护的视图中,该视图仅考虑/汇总过去 8 周的情况。我认为连续聚合是正确的方法,但我无法使其工作(https://blog.timescale.com/blog/continuous-aggregates-faster-queries-with-automatically-maintained-materialized-views/)。看来我需要以某种方式使用 time_bucket-function,但实际上我不知道如何。有什么想法/提示吗?

我将 postgres 与 timescaledb 一起使用。

编辑:这给了我所需的输出,但我不能将其放入连续的聚合中

SELECT id,
       extract(dow from observed_date) AS weekday,
       observed_hour,
       sum(minutes_per_hour_used)
FROM base_table
WHERE observed_date >= now() - interval '8 weeks'
GROUP BY id, weekday, observed_hour
ORDER BY id, weekday, observed_hour;
Run Code Online (Sandbox Code Playgroud)

编辑:在此前面添加

CREATE VIEW my_view
    WITH (timescaledb.continuous) AS
Run Code Online (Sandbox Code Playgroud)

给我[0A000] ERROR: invalid SELECT query for continuous aggregate

k_r*_*rus 5

连续聚合需要按以下方式分组time_bucket

SELECT <grouping_exprs>, <aggregate_functions>
    FROM <hypertable>
[WHERE ... ]
GROUP BY time_bucket( <const_value>, <partition_col_of_hypertable> ),
         [ optional grouping exprs>]
[HAVING ...]
Run Code Online (Sandbox Code Playgroud)

它应该应用于分区列,该列通常是超表创建中使用的时间维度列。也不支持 ORDER BY。

对于问题中的聚合查询,没有时间列用于分组。时间列也不weekdayobserved_hour有效列,因为它们不会随时间增加,而是定期重复它们的值。weekday每 7 天重复一次,observed_hour每 24 小时重复一次。这打破了连续聚合的要求。

由于此用例没有现成的解决方案,一种方法是使用连续聚合来减少目标查询的数据量,例如按天存储:

CREATE MATERIALIZED VIEW daily
WITH (timescaledb.continuous) AS
SELECT id,
       time_bucket('1day', observed_date) AS day,
       observed_hour,
       sum(minutes_per_hour_used)
FROM base_table
GROUP BY 1, 2, 3;
Run Code Online (Sandbox Code Playgroud)

然后在其之上执行目标聚合查询:

SELECT id,
       extract(dow from day) AS weekday,
       observed_hour,
       sum(minutes_per_hour_used)
FROM daily
WHERE day >= now() - interval '8 weeks'
GROUP BY id, weekday, observed_hour
ORDER BY id, weekday, observed_hour;
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用PostgreSQL 的物化视图,并借助自定义作业定期刷新它,该自定义作业由 TimescaleDB 的作业调度框架运行。请注意,刷新将重新计算整个视图,在示例中涵盖 8 周的数据。物化视图可以根据原始表base_table或上面建议的连续聚合来编写。