Förutsatt datatyp jsonb
och att du vill slå samman poster för varje JSON-array som delar samma "id"-värde.
Postgres 9.5
gör det enklare med den nya sammansättningen operator ||
för jsonb
värden
:
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);
FULL [OUTER] JOIN
ser till att du inte förlorar rekord utan matchning i den andra arrayen.
Typen jsonb
har den bekväma egenskapen att endast behålla det senaste värdet för varje nyckel i posten. Därför slås den dubbla 'id'-nyckeln i resultatet samman automatiskt.
Postgres 9.5-manualen ger också råd om:
Postgres 9.4
Är lite mindre bekvämt. Min idé skulle vara att extrahera arrayelement och sedan extrahera alla nyckel/värdepar, UNION
båda resultaten samlas till en enda ny jsonb
värden per id-värde och slutligen aggregeras till en enda array.
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;
Casten till jsonb
tar bort dubbletter av nycklar. Alternativt kan du använda UNION
att vika dubbletter (till exempel om du vill ha json
som resultat). Testa vilket som är snabbare för ditt fall.
Relaterat:
- Hur förvandlar man json-array till postgres-array?
- Sammanfogar sammanfogande JSON(B)-kolumner i fråga