从 postgresql 14+ 中的 jsonb 列查询并返回聚合

问题描述 投票:0回答:1

有没有一种有效的方法来聚合 postgresql 中

jsonb
列中的数据?给出表格

userdata(id STRING, data JSONB)

和数据

123.abc, { "dis": ["close"] }
123.abc, { "purpose": {"score": 0.1, "text": "hi"}, "dis": ["hello", "close"]}
123.abc, { "dis": ["bye"], "dir": 1}
123.abc, {}
567.bhy, { "dis", ["close"]}

我试图得到以下结果:

123.abc, { "dis": ["close", "hello", "bye"], "purpose": {"score": 0.1, "text": "hi", "dir": 1} 
567.bhy, {"dis", ["close"]}

正如您所注意到的,我希望在按 id 索引的所有记录中具有唯一的键值(例如

"dis"
)。

我尝试使用

jsonb_agg
jsonb_array_elements
获取值。我无法聚合所有键和不同的值。我不知道如何使用
jsonb_each
来获取所有密钥

我尝试过类似的方法来获得一把钥匙。

select id,
       (select jsonb_agg(t->>'dis') from jsonb_array_elements(data::jsonb) as x(t) where t->>'dis' is not null) as sdata
from mytable where id='123.abc'

如有任何有关查询的帮助,我们将不胜感激。

sql postgresql jsonb
1个回答
0
投票

您需要首先将每一行分解为键/值对。然后(有条件地,如果它是

dis
键)将值分解为数组。

然后在两个级别上重新聚合,首先是

dis
,然后是所有属性。

select
  t.id,
  jsonb_object_agg(t.key, case when t.key = 'dis' then t.value else t.value->0 end) as final_json
from (
    select
      mt.id,
      props.key,
      jsonb_agg(coalesce(j.dis, props.value)) as value
    from mytable as mt
    cross join jsonb_each(mt.t) as props
    left join jsonb_array_elements(case when props.key = 'dis' then props.value end) as j(dis) on 1=1
    group by
      mt.id,
      props.key
) t
group by
  t.id;

db<>小提琴

© www.soinside.com 2019 - 2024. All rights reserved.