Vorausgesetzt Datentyp jsonb
und dass Sie Datensätze jedes JSON-Arrays zusammenführen möchten, die denselben 'id'-Wert haben.
Postgres 9.5
macht es einfacher mit dem neuen concatenate Operator ||
für jsonb
Werte
:
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);
Der FULL [OUTER] JOIN
stellt sicher, dass Sie keine Datensätze ohne Übereinstimmung im anderen Array verlieren.
Der Typ jsonb
hat die bequeme Eigenschaft, nur den neuesten Wert für jeden Schlüssel im Datensatz zu behalten. Daher wird der doppelte 'id'-Schlüssel im Ergebnis automatisch zusammengeführt.
Das Postgres 9.5-Handbuch empfiehlt auch:
Postgres 9.4
Ist etwas weniger bequem. Meine Idee wäre, Array-Elemente zu extrahieren und dann alle Schlüssel/Wert-Paare zu extrahieren, UNION
beide Ergebnisse werden zu einem einzigen neuen jsonb
aggregiert Werte pro ID-Wert und schließlich zu einem einzigen Array aggregieren.
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;
Die Umwandlung in jsonb
entfernt doppelte Schlüssel. Alternativ können Sie UNION
verwenden um Duplikate zu falten (zum Beispiel, wenn Sie json
als Ergebnis). Testen Sie, was für Ihren Fall schneller ist.
Verwandte:
- Wie wandle ich ein JSON-Array in ein Postgres-Array um?
- Merging Concatenating JSON(B)-Spalten in Abfrage