Postgres concat地图中的不同键

时间:2018-10-22 18:41:47

标签: postgresql aggregate-functions jsonb

Postgres 9.6 中的jsonb函数的哪些组合可用于汇总地图的不同键? (同一密钥的不同值将导致该密钥的随机值。)

例如给出以下数据:

WITH tbl(id, j) as (
values
    (1, '{"key1": "val1"}'::jsonb),
    (1, '{"key2": "val2"}'),
    (1, '{"key2": "val2"}'),
    (2, '{"key3": "val3"}')
)
SELECT id, <what aggregate fn?>(data) FROM tbl GROUP BY 1

我们如何返回经过重复数据删除和合并的结果集?

id  | j
----|----------------------------------
1   | {"key1": "val1", "key2": "val2"}
2   | {"key3": "val3"}

1 个答案:

答案 0 :(得分:2)

在从jsonb_object_agg()中获得的(key, value)对中使用jsonb_each(),用于横向连接:

with tbl(id, j) as (
values
    (1, '{"key1": "val1"}'::jsonb),
    (1, '{"key2": "val2"}'),
    (1, '{"key2": "val2"}'),
    (2, '{"key3": "val3"}')
)
select id, jsonb_object_agg(key, value)
from tbl 
cross join jsonb_each(j)
group by 1

 id |         jsonb_object_agg         
----+----------------------------------
  1 | {"key1": "val1", "key2": "val2"}
  2 | {"key3": "val3"}
(2 rows)

更新。您可以创建自定义聚合:

create or replace function jsonb_object_merge(jsonb, jsonb)
returns jsonb language plpgsql as $$
begin
    return jsonb_object_agg(key, value)
    from ( 
        select key, value from jsonb_each($2)
        union   
        select key, value from jsonb_each($1)
    ) s;
end $$;

create aggregate my_jsonb_object_agg(jsonb)
(
    sfunc = jsonb_object_merge,
    stype = jsonb
);

在更复杂的查询(以及其他聚合)中可能有用:

with tbl(id, j, v) as (
values
    (1, '{"key1": "val1", "key4": "val4"}'::jsonb, 1),
    (1, '{"key2": "val2"}', 1),
    (1, '{"key2": "val3"}', 1),
    (2, '{"key3": "val3"}', 1)
)
select id, my_jsonb_object_agg(j), sum(v)
from tbl
group by 1

 id |               my_jsonb_object_agg                | sum 
----+--------------------------------------------------+-----
  1 | {"key1": "val1", "key2": "val2", "key4": "val4"} |   3
  2 | {"key3": "val3"}                                 |   1
(2 rows)