Za předpokladu datový typ jsonb
a že chcete sloučit záznamy každého pole JSON, které sdílí stejnou hodnotu 'id'.
Postgres 9.5
zjednodušuje to pomocí nového řetězení operátor ||
pro jsonb
hodnoty
:
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
zajišťuje, že neztratíte záznamy bez shody v druhém poli.
Typ jsonb
má pohodlnou vlastnost zachovat pouze nejnovější hodnotu pro každý klíč v záznamu. Proto je duplicitní klíč 'id' ve výsledku sloučen automaticky.
Manuál Postgres 9.5 také radí:
Postgres 9.4
Je to trochu méně pohodlné. Můj nápad by byl extrahovat prvky pole a poté extrahovat všechny páry klíč/hodnota, UNION
oba výsledky agregovat do jednoho nového jsonb
hodnoty na hodnotu id a nakonec agregovat do jednoho pole.
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;
Odeslání do jsonb
odstraní duplicitní klíče. Alternativně můžete použít UNION
pro skládání duplikátů (například pokud chcete json
jako výsledek). Vyzkoušejte, co je ve vašem případě rychlejší.
Související: