Postgres变更表累积视图的查询优化方案问询
寻求无冗余聚合的窗口函数查询方案
表结构与初始化数据
我有一张存储变更记录的changes表,表结构定义如下:
CREATE TABLE IF NOT EXISTS changes ( entity_id TEXT NOT NULL, column_id TEXT NOT NULL, value JSONB NOT NULL, updated_at TIMESTAMP NOT NULL );
初始化数据及表数据展示:
INSERT INTO changes VALUES ('1', 'height', to_jsonb(140), '01-01-2021 00:00:00'::TIMESTAMP); INSERT INTO changes VALUES ('1', 'weight', to_jsonb(30), '01-01-2021 00:00:00'::TIMESTAMP); INSERT INTO changes VALUES ('1', 'height', to_jsonb(145), '01-02-2021 00:00:00'::TIMESTAMP); INSERT INTO changes VALUES ('1', 'weight', to_jsonb(34),'01-03-2021 00:00:00'::TIMESTAMP);
表中现有数据:
entity_id | column_id | value | updated_at -----------+-----------+-------+--------------------- 1 | height | 140 | 2021-01-01 00:00:00 1 | weight | 30 | 2021-01-01 00:00:00 1 | height | 145 | 2021-01-02 00:00:00 1 | weight | 34 | 2021-01-03 00:00:00
期望结果
需要生成该表的累积视图,结果示例如下:
entity_id | height | weight | updated_at -----------+--------+--------+--------------------- 1 | 140 | 30 | 2021-01-01 00:00:00 1 | 145 | 30 | 2021-01-02 00:00:00 1 | 145 | 34 | 2021-01-03 00:00:00
当前已有方案
方案1:使用json_object_agg聚合
SELECT entity_id, coalesce(change->'height', lag(change->'height', 1, null) over (partition by entity_id order by updated_at)) as height, coalesce(change->'weight', lag(change->'weight', 1, null) over (partition by entity_id order by updated_at)) as weight, updated_at FROM ( SELECT entity_id, json_object_agg(column_id, value) as change, updated_at FROM changes GROUP BY entity_id, updated_at ) as changes;
但我不想使用json_object_agg,认为存在无需冗余聚合的实现方式。
方案2:CTE聚合优化版
经优化后的CTE版本如下,但仍觉得存在冗余聚合,并非最优解:
with cte as ( SELECT entity_id, max(case when column_id = 'height' then value::int end) as height, max(case when column_id = 'weight' then value::int end) as weight, updated_at from changes GROUP by entity_id, updated_at ) select entity_id, coalesce(height, lag(height) over (partition by entity_id order by updated_at)) as height, coalesce(weight, lag(weight) over (partition by entity_id order by updated_at)) as weight, updated_at from cte;
需求
寻求更优的基于窗口函数的查询方案,避免冗余聚合操作。
内容的提问来源于stack exchange,提问作者Vladislav Mikitich
相关产品推荐
相关产品推荐

