2017-10-19 60 views
1

我有一个包含JSON数组的JSONB列。我现在需要将所有行中的所有不同值存入单个数组。flatten/concat-aggregate JSONB数组

输入:

id | values 
----------- 
1 | [x, y, z] 
2 | [a, b, x] 

所需的输出:

result 
--------------- 
[a, b, x, y, z] 

我不能只用jsonb_aggDISTINCT,因为这会返回一个二维数组,我找不到任何扁平化或concat集合函数。我该如何解决这个问题?

回答

1

使用聚合之前,您应该UNNEST数组:

with my_table(id, data) as (
values 
    (1, '["x", "y", "z"]'::jsonb), 
    (2, '["a", "b", "x"]') 
) 

select jsonb_agg(distinct value) 
from my_table, jsonb_array_elements_text(data); 

     jsonb_agg   
--------------------------- 
["a", "b", "x", "y", "z"] 
(1 row) 

您可以将结果:

with my_table(id, data) as (
values 
    (1, '["x", "y", "z"]'::jsonb), 
    (1, '["a", "b", "x"]'), 
    (2, '["1", "2", "3"]'), 
    (2, '["2", "3", "4"]') 
) 

select id, jsonb_agg(distinct value) 
from my_table, jsonb_array_elements_text(data) 
group by id; 

id |   jsonb_agg   
----+--------------------------- 
    1 | ["a", "b", "x", "y", "z"] 
    2 | ["1", "2", "3", "4"] 
(2 rows) 
+0

谢谢!你知道在窗口函数中是否有任何方法使用这种方法? (就像组合所有具有相同'id'的行)。 –

+0

您不需要窗口函数,请参阅已更新的答案。 – klin

0

如果你不关心不同的元素,那么你可以定义你自己的聚合器

CREATE AGGREGATE jsonb_concat_agg (jsonb) 
(
    sfunc = jsonb_concat, 
    stype = jsonb, 
    initcond = '[]' 
); 

那么这将是

SELECT jsonb_concat_agg(values); 

其结果将是

result 
--------------- 
[a, b, x, x, y, z] 
+0

@a_horse_with_no_name不是真的,这里[a,b,x]和[x,y,z]是不同的。他对数组中的不同元素感兴趣,而不是独特的数组 –