PostgreSQL 创建物化视图,根据字段和 table 列将 JSON 数组中的对象汇总到特定列中

PostgreSQL create materialized view that sums objects in JSON array into specific columns based on field and table column

给出以下 table:

create table entries (
    user_id integer,
    locations jsonb
);

我想创建一个包含以下结构的物化视图。这些列应从零开始,并根据位置中的内容相加。

create table entries_locations_extracted (
    user_id integer,
    location_1_a integer,
    location_1_b integer,
    location_2_a integer,
    location_2_b integer
);

位置将始终是一个 JSON 数组,具有以下结构。阵列中可能存在多个位置。每个用户可能存在多个条目。

insert into entries (user_id, locations) values (123, '[
    { location=1, a=1,  b=2 },
    { location=2, a=3,  b=1 },
    { location=2, a=10, b=20 },
    { location=1, a=2,  b=3 },
]')
insert into entries (user_id, locations) values (123, '[
    { location=1, a=100, b=200 },
]')

鉴于上面的插入。物化视图应包含以下行:

| user_id | location_1_a | location_1_b | location_2_a | location_2_b |
-----------------------------------------------------------------------
| 123     | 103          | 205          | 13           | 21           |

您可以为此使用 aggregate with a filter and a lateral query to expand the array

SELECT
    user_id,
    SUM((loc->>'a')::int) FILTER (WHERE loc->'location' = '1') AS location_1_a,
    SUM((loc->>'b')::int) FILTER (WHERE loc->'location' = '1') AS location_1_b,
    SUM((loc->>'a')::int) FILTER (WHERE loc->'location' = '2') AS location_2_a,
    SUM((loc->>'b')::int) FILTER (WHERE loc->'location' = '2') AS location_2_b
FROM
    entries,
    jsonb_array_elements(locations) AS loc
GROUP BY
    user_id;