聚合连接 jsonb 数组

Aggregate concatenate jsonb arrays

有一个名为 example_table 的 table,其中有一列名为 example_column,类型为 JSONB,并且该列中的每个值都是一个数组。

2 行中的值为:[1, 2] 和 [3]

如何聚合连接 example_column 中的值?

结果应该是:[1, 2, 3]

我尝试使用:

select json_agg(example_column) from example_table

但是 returns [[1, 2,], [3]]

使用函数jsonb_array_elements(example_column),例子:

with example_table(example_column) as (
values
    (jsonb '[1, 2]'),
    (jsonb '[3]')
)

select jsonb_agg(value)
from example_table
cross join jsonb_array_elements(example_column) 

jsonb_agg 
-----------
 [1, 2, 3]
(1 row)

您可以定义聚合元素的排序顺序and/or删除重复项,例如:

with example_table(id, example_column) as (
values
    (1, jsonb '[1, 2]'),
    (2, jsonb '[3]'),
    (3, jsonb '[3, 1]')
)

select 
    jsonb_agg(value order by id) as agg1,
    jsonb_agg(value order by value) as agg2,
    jsonb_agg(distinct value order by value) as agg3
from example_table
cross join jsonb_array_elements(example_column) 

      agg1       |      agg2       |   agg3    
-----------------+-----------------+-----------
 [1, 2, 3, 3, 1] | [1, 1, 2, 3, 3] | [1, 2, 3]
(1 row)

如果您经常需要这样做,您可以为此创建自己的聚合:

create function combine_jsonb_arrays(p_array_1 jsonb, p_array_2 jsonb) 
  returns jsonb
as
$$
  select jsonb_agg(t.val order by t.val)
  from (
    select *
    from jsonb_array_elements(p_array_1) as x1(val)
    union all
    select *
    from jsonb_array_elements(p_array_2) as x2(val)
  ) t;
$$
language sql;

create aggregate jsonb_elements_agg(jsonb)
(
  sfunc = combine_jsonb_arrays,
  stype = jsonb
);

那么你可以这样使用它:

select jsonb_elements_agg(example_column)
from example_table;