2017-10-19 49 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]是不同的。他對數組中的不同元素感興趣,而不是獨特的數組 –