Explicación
La subselección en FROM
cláusula de su UPDATE
devuelve tres filas Pero cada fila en la tabla de destino solo se puede actualizar una vez en un solo UPDATE
dominio. El resultado es que solo ves el efecto de one de esas tres filas.
O, en palabras de el manual :
Aparte:no llame a su subconsulta "cte". No es una expresión de tabla común .
Correcto 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 aquí
Usa jsonb_set()
en cada objeto (elemento de matriz) antes de volver a agregarlos en una matriz. Primero al nivel de la hoja y nuevamente al nivel más profundo.
Agregué id
como PRIMARY KEY
a la mesa. Necesitamos una columna única para mantener las filas separadas.
El ORDER BY
agregado puede o no ser requerido. Se agregó para garantizar el pedido original.
Por supuesto, si sus datos son tan regulares como la muestra, un diseño relacional con columnas dedicadas podría ser una alternativa más simple. Ver