Forklaring
Undervalget i FROM
klausul i din UPDATE
returnerer tre rækker. Men hver række i måltabellen kan kun opdateres én gang i en enkelt UPDATE
kommando. Resultatet er, at du kun ser effekten af én af disse tre rækker.
Eller med ordene fra manualen :
Til side:Kald ikke din underforespørgsel "cte". Det er ikke et fælles tabeludtryk .
Korrekt 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 her
Brug jsonb_set()
på hvert objekt (array-element), før de aggregeres tilbage til et array. Først på bladniveauet og igen på det dybere plan.
Jeg tilføjede id
som PRIMARY KEY
til bordet. Vi har brug for en unik kolonne for at holde rækkerne adskilt.
Den tilføjede ORDER BY
kan være påkrævet eller ikke. Tilføjet det for at garantere original ordre.
Selvfølgelig, hvis dine data er lige så regelmæssige som eksemplet, kan et relationelt design med dedikerede kolonner være et enklere alternativ. Se