Обяснение
Подизборът в FROM
клауза на вашия UPDATE
връща три редове. Но всеки ред в целевата таблица може да бъде актуализиран само веднъж в една UPDATE
команда. Резултатът е, че виждате ефекта само на един от тези три реда.
Или, по думите на ръководството :
Настрана:не наричайте подзаявката си "cte". Това не е общ израз на таблица .
Правилен 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 тук
Използвайте jsonb_set()
върху всеки обект (елемент от масив), преди да ги агрегира обратно в масив. Първо на ниво лист и отново на по-дълбоко ниво.
Добавих id
като PRIMARY KEY
към масата. Имаме нужда от уникална колона, за да запазим редовете разделени.
Добавеният ORDER BY
може или не може да се изисква. Добавих го, за да гарантирам оригиналната поръчка.
Разбира се, ако вашите данни са редовни като извадката, релационен дизайн със специални колони може да бъде по-проста алтернатива. Вижте