postgresql 如何在SQL中合并两行(或多行)jsonb数组为一行

ss2ws0br  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(3)|浏览(315)

我使用的是postgres,我在一个名为observation的列中的数组中有多个jsonb条目。输入为'[{"a": 1}, {"b": 2}, {"c": 0.5}]'::jsonb。有多个行,每个行中有多个json元素。我想把它们合并成一行中的一个大条目,这样我就只会有一列的一个观察结果。
我试过以下方法

INSERT INTO data
SELECT jsonb_agg(observation) AS concatenated_json
FROM (
  SELECT observation
  FROM test
) AS subquery;

字符串
但是我得到的结果是一个数组的数组。我不想得到多个数组,只要一个。

3phpmpom

3phpmpom1#

INSERT INTO data
SELECT jsonb_agg(s.elements) FROM (
    SELECT jsonb_array_elements(observation) FROM test
) AS s(elements);

字符串
使用jsonb_array_elements()将json数组扩展为一组json值。举例来说:

[{"a": 1}, {"b": 2}, {"c": 0.5}]
[{"d": 2.2}, {"e": 2.4}, {"f": 3.5}]
[{"g": 1.7}, {"h": 5.4}, {"i": 8.9}]


(3排)
将转换为9行json值:

{"a": 1}
{"b": 2}
{"c": 0.5}
{"d": 2.2}
{"e": 2.4}
{"f": 3.5}
{"g": 1.7}
{"h": 5.4}
{"i": 8.9}


然后我们使用jsonb_agg()将json值聚合到表data中以输出一行:

[{"a": 1}, {"b": 2}, {"c": 0.5}, {"d": 2.2}, {"e": 2.4}, {"f": 3.5}, {"g": 1.7}, 
{"h": 5.4}, {"i": 8.9}]

wixjitnu

wixjitnu2#

可以使用jsonb_object_agg

select jsonb_agg((select jsonb_object_agg(k1.key, k1.value) 
     from jsonb_array_elements(t.observation) k 
     cross join jsonb_each(k.value) k1)) 
from test t

字符串
See fiddle
对于每一行,该查询将把observations数组元素中的所有键值对合并到一个对象中。然后,合并的对象被聚合到单个数组中。

mftmpeh8

mftmpeh83#

您可以创建一个用户定义的聚合,它可以非常简单地完成您想要的任务:

create aggregate jsonb_concat_agg(jsonb) (stype=jsonb, sfunc=jsonb_concat);

字符串
然后将它与GROUP BY一起使用,或者因为您只需要一行,所以不使用GROUP BY:

with t as (select '[{"a":1},{"b":2},{"c":3}]'::jsonb p union select '[{"d":4},{"e":5},{"f":6}]'::jsonb) 
select jsonb_concat_agg(p) from t;
------------------------------------------------------------
[{"a": 1}, {"b": 2}, {"c": 3}, {"d": 4}, {"e": 5}, {"f": 6}]


一方面,它比必须将对象解嵌套然后重新组装它们要好,另一方面,阅读您的代码的人可能会被看起来像内置函数的东西所迷惑,但实际上不是。

相关问题