PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

UPDATE с jsonb_set() засяга само един обект във вложен масив

Обяснение

Подизборът в 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 може или не може да се изисква. Добавих го, за да гарантирам оригиналната поръчка.

Разбира се, ако вашите данни са редовни като извадката, релационен дизайн със специални колони може да бъде по-проста алтернатива. Вижте




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Няма достъп до таблица без име на public.table. Има ли начин да се отървем от обществеността?

  2. Как да конвертирате точков текст в геометрия

  3. Как работи функцията timezone() в PostgreSQL

  4. Връщане на редове, съответстващи на елементи от входния масив във функцията plpgsql

  5. RailsTutorial 3.2 Ch 11 - Грешка в синтаксиса на PostgreSQL нарушава емисията за състояние