Förklaring
Undermarkeringen i FROM
klausul i din UPDATE
returnerar tre rader. Men varje rad i måltabellen kan bara uppdateras en gång i en enda UPDATE
kommando. Resultatet är att du bara ser effekten av en av dessa tre rader.
Eller, med orden i handboken :
Bortsett från:kalla inte din underfråga "cte". Det är inte ett vanligt tabelluttryck .
Rätt 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<>fiol här
Använd jsonb_set()
på varje objekt (matriselement) innan de aggregeras tillbaka till en matris. Först på lövnivån och igen på den djupare nivån.
Jag lade till id
som PRIMARY KEY
till bordet. Vi behöver någon unik kolumn för att hålla raderna åtskilda.
Den tillagda ORDER BY
kan eller kanske inte krävs. Lade till det för att garantera den ursprungliga beställningen.
Naturligtvis, om din data är lika regelbunden som provet, kan en relationsdesign med dedikerade kolumner vara ett enklare alternativ. Se