sql >> Databasteknik >  >> RDS >> PostgreSQL

UPPDATERING med jsonb_set() påverkar bara ett objekt i kapslad array

Förklaring

Undermarkeringen i FROM klausul i din UPDATE returnerar tre rader. Men varje rad i måltabellen kan bara uppdateras en gång i en enda UPDATE kommando. Resultatet är att du bara ser effekten av en av dessa tre rader.

Eller, med orden i handboken :

Bortsett från:kalla inte din underfråga "cte". Det är inte ett vanligt tabelluttryck .

Rätt 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<>fiol här

Använd jsonb_set() på varje objekt (matriselement) innan de aggregeras tillbaka till en matris. Först på lövnivån och igen på den djupare nivån.

Jag lade till id som PRIMARY KEY till bordet. Vi behöver någon unik kolumn för att hålla raderna åtskilda.

Den tillagda ORDER BY kan eller kanske inte krävs. Lade till det för att garantera den ursprungliga beställningen.

Naturligtvis, om din data är lika regelbunden som provet, kan en relationsdesign med dedikerade kolumner vara ett enklare alternativ. Se




  1. Hur får man ett värde från den senast infogade raden?

  2. Vad är användningen av GO i SQL Server Management Studio &Transact SQL?

  3. Error sql:Konverteringen av en varchar-datatyp till en datetime-datatyp resulterade i ett värde utanför intervallet

  4. pandas read_sql med en lista med värden för WHERE-villkoret