有没有一种有效的方法来聚合 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'
如有任何有关查询的帮助,我们将不胜感激。
您需要首先将每一行分解为键/值对。然后(有条件地,如果它是
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;