Vysvětlení
Podvýběr v FROM
klauzule vašeho UPDATE
vrátí tři řádky. Ale každý řádek v cílové tabulce lze aktualizovat pouze jednou v jediném UPDATE
příkaz. Výsledkem je, že uvidíte pouze efekt jednoho z těchto tří řádků.
Nebo slovy příručky :
Stranou:neříkejte svému poddotazu „cte“. Nejedná se o běžný tabulkový výraz .
Správné 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 zde
Použijte jsonb_set()
na každý objekt (prvek pole) před jejich agregací zpět do pole. Nejprve na úrovni listů a znovu na hlubší úrovni.
Přidal jsem id
jako PRIMARY KEY
ke stolu. Potřebujeme nějaký jedinečný sloupec, abychom udrželi řádky oddělené.
Přidáno ORDER BY
může a nemusí být vyžadováno. Přidáno, aby byla zaručena původní objednávka.
Samozřejmě, pokud jsou vaše data stejně pravidelná jako ukázka, může být jednodušší alternativou relační návrh s vyhrazenými sloupci. Viz