2017-10-19 11 views
1

JSON配列を含むJSONBの列があります。私は今すべての行からすべての異なる値を1つの配列に取得する必要があります。JSONB配列のフラット/連結集合

入力:

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

所望の出力:

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

それは2次元配列を返しますので、私はちょうどDISTINCTjsonb_aggを使用することはできません、と私は任意のフラット化を見つけることができませんまたは集合関数を連結します。これをどうすれば解決できますか?

答えて

1

あなたは集計を使用する前に、配列をネスト解除する必要があります

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

おかげだろう

SELECT jsonb_concat_agg(values); 

だろう!このアプローチをウィンドウ関数内で使用する方法があるかどうか知っていますか? (同じ 'id'を持つ行のすべての配列を結合するのと同じです。) –

+0

ウィンドウ関数は必要ありません。更新された答えを見てください。 – klin

0

あなたは個別の要素を気にしないなら、あなたは可能性が自分のアグリゲーターを定義する

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

そして、それは結果が

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

@a_horse_with_no_name実際には、ここ[a、b、x]と[x、y、z]は区別されません。彼は別個の配列ではなく、配列の別個の要素に興味があります –