Spiegazione
La sottoselezione nel FROM
clausola del tuo UPDATE
restituisce tre righe. Ma ogni riga nella tabella di destinazione può essere aggiornata solo una volta in un unico UPDATE
comando. Il risultato è che vedi solo l'effetto di uno di queste tre righe.
Oppure, nelle parole del il manuale :
A parte:non chiamare la tua sottoquery "cte". Non è un Espressione di tabella comune .
UPDATE
corretto
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<>violino qui
Usa jsonb_set()
su ciascun oggetto (elemento array) prima di aggregarli nuovamente in un array. Prima a livello fogliare e poi ancora a livello più profondo.
Ho aggiunto id
come PRIMARY KEY
al tavolo. Abbiamo bisogno di una colonna univoca per mantenere le righe separate.
Il ORDER BY
aggiunto può o non può essere richiesto. Aggiunto per garantire l'ordine originale.
Ovviamente, se i tuoi dati sono regolari come il campione, un design relazionale con colonne dedicate potrebbe essere un'alternativa più semplice. Vedi