Erklärung
Die Unterauswahl im FROM
-Klausel Ihres UPDATE
gibt drei zurück Reihen. Aber jede Zeile in der Zieltabelle kann nur einmal aktualisiert werden in einem einzigen UPDATE
Befehl. Das Ergebnis ist, dass Sie nur den Effekt von einem sehen dieser drei Zeilen.
Oder in den Worten von dem Handbuch :
Übrigens:Nennen Sie Ihre Unterabfrage nicht "cte". Es ist kein allgemeiner Tabellenausdruck .
Richtiges UPDATE
UPDATE table_ t
SET value_ = jsonb_set(value_, '{iProps}', sub2.new_prop, false)
FROM (
SELECT id
, jsonb_agg(jsonb_set(prop, '{value, rules}', new_rules, false)
ORDER BY idx1) AS new_prop
FROM (
SELECT t.id, arr1.prop, arr1.idx1
, jsonb_agg(jsonb_set(rule, '{ao,sc}', rule #> '{ao,sc,name}', false)
ORDER BY idx2) AS new_rules
FROM table_ t
, jsonb_array_elements(value_->'iProps') WITH ORDINALITY arr1(prop,idx1)
, jsonb_array_elements(prop->'value'->'rules') WITH ORDINALITY arr2(rule,idx2)
GROUP BY t.id, arr1.prop, arr1.idx1
) sub1
GROUP BY id
) sub2
WHERE t.id = sub2.id;
db<>fiddle hier
Verwenden Sie jsonb_set()
auf jedem Objekt (Array-Element), bevor sie wieder zu einem Array aggregiert werden. Zuerst auf der Blattebene und noch einmal auf der tieferen Ebene.
Ich habe id
hinzugefügt als PRIMARY KEY
zum Tisch. Wir brauchen eine eindeutige Spalte, um die Zeilen getrennt zu halten.
Der hinzugefügte ORDER BY
kann erforderlich sein oder nicht. Hinzugefügt, um die ursprüngliche Bestellung zu garantieren.
Wenn Ihre Daten so regelmäßig sind wie die Stichprobe, könnte ein relationales Design mit dedizierten Spalten natürlich eine einfachere Alternative sein. Siehe