Asumiendo tipo de datos jsonb
y que desea fusionar registros de cada matriz JSON que comparten el mismo valor de 'id'.
Postgres 9.5
lo simplifica con el nuevo 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);
El FULL [OUTER] JOIN
se asegura de no perder registros sin coincidencia en la otra matriz.
El tipo jsonb
tiene la propiedad conveniente de mantener solo el valor más reciente para cada clave en el registro. Por lo tanto, la clave 'id' duplicada en el resultado se fusiona automáticamente.
El manual de Postgres 9.5 también aconseja:
Postgres 9.4
Es un poco menos conveniente. Mi idea sería extraer elementos de la matriz, luego extraer todos los pares clave/valor, UNION
ambos resultados, agregados en un solo nuevo jsonb
valores por valor de identificación y finalmente se agregan en una sola 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;
El elenco a jsonb
elimina llaves duplicadas. Alternativamente, podría usar UNION
para plegar duplicados (por ejemplo, si desea json
como resultado). Prueba cuál es más rápido para tu caso.
Relacionado:
- ¿Cómo convertir una matriz json en una matriz postgres?
- Fusionar columnas JSON(B) concatenadas en la consulta