Supondo tipo de dados
jsonb
e que você deseja mesclar registros de cada matriz JSON que compartilham o mesmo valor 'id'. Postgres 9.5
torna tudo mais simples com o novo concatenar operador
||
para jsonb
valores
:SELECT json_agg(elem1 || elem2) AS result
FROM (
SELECT elem1->>'id' AS id, elem1
FROM (
SELECT '[
{"id":1, "percent":12.50},
{"id":2, "percent":75.00},
{"id":3, "percent":12.50}
]'::jsonb AS js
) t, jsonb_array_elements(t.js) elem1
) t1
FULL JOIN (
SELECT elem2->>'id' AS id, elem2
FROM (
SELECT '[
{"id": 1, "a": "text1a", "b": "text1b", "percent":12.50},
{"id": 2, "a": "text2a", "b": "text2b", "percent":75.00},
{"id": 3, "a": "text3a", "b": "text3b", "percent":12.50}]'::jsonb AS js
) t, jsonb_array_elements(t.js) elem2
) t2 USING (id);
O
FULL [OUTER] JOIN
garante que você não perca registros sem correspondência na outra matriz. O tipo
jsonb
tem a propriedade conveniente de manter apenas o valor mais recente para cada chave no registro. Portanto, a chave 'id' duplicada no resultado é mesclada automaticamente. O manual do Postgres 9.5 também aconselha:
Postgres 9.4
É um pouco menos conveniente. Minha ideia seria extrair elementos de matriz e extrair todos os pares de chave/valor,
UNION
ambos os resultados, agregados em um único novo jsonb
valores por valor de id e, finalmente, agregar em uma única matriz. SELECT json_agg(j) -- ::jsonb
FROM (
SELECT json_object_agg(key, value)::jsonb AS j
FROM (
SELECT elem->>'id' AS id, x.*
FROM (
SELECT '[
{"id":1, "percent":12.50},
{"id":2, "percent":75.00},
{"id":3, "percent":12.50}]'::jsonb AS js
) t, jsonb_array_elements(t.js) elem, jsonb_each(elem) x
UNION ALL -- or UNION, see below
SELECT elem->>'id' AS id, x.*
FROM (
SELECT '[
{"id": 1, "a": "text1a", "b": "text1b", "percent":12.50},
{"id": 2, "a": "text2a", "b": "text2b", "percent":75.00},
{"id": 3, "a": "text3a", "b": "text3b", "percent":12.50}]'::jsonb AS js
) t, jsonb_array_elements(t.js) elem, jsonb_each(elem) x
) t
GROUP BY id
) t;
A conversão para
jsonb
remove chaves duplicadas. Alternativamente, você pode usar UNION
dobrar duplicatas (por exemplo, se você quiser json
como resultado). Teste qual é mais rápido para o seu caso. Relacionado:
- Como transformar array json em array postgres?
- Mesclando colunas JSON(B) de concatenação na consulta