PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

UPDATE z jsonb_set() wpływa tylko na jeden obiekt w zagnieżdżonej tablicy

Wyjaśnienie

Wybór podrzędny w FROM klauzula Twojej UPDATE zwraca trzy wydziwianie. Ale każdy wiersz w tabeli docelowej można zaktualizować tylko raz w jednej UPDATE Komenda. Efekt jest taki, że widzisz tylko efekt jednego z tych trzech rzędów.

Lub słowami instrukcji :

Na marginesie:nie nazywaj swojego podzapytania „cte”. To nie jest wspólne wyrażenie tabelowe .

Właściwa 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 tutaj

Użyj jsonb_set() na każdym obiekcie (element tablicy) przed ich ponownym zagregowaniem w tablicę. Najpierw na poziomie liści i ponownie na głębszym poziomie.

Dodałem id jako PRIMARY KEY na stół. Potrzebujemy jakiejś unikalnej kolumny, aby oddzielić wiersze.

Dodany ORDER BY może, ale nie musi być wymagane. Dodano go, aby zagwarantować oryginalne zamówienie.

Oczywiście, jeśli Twoje dane są tak regularne jak próbka, projekt relacyjny z dedykowanymi kolumnami może być prostszą alternatywą. Zobacz




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcje agregujące na wielu połączonych tabelach

  2. Trwały błąd limitu czasu H12 dla wszystkich żądań, które uruchamiają zapytanie do bazy danych

  3. Partycjonowanie PostgreSQL+tabeli:nieefektywne max() i min()

  4. Skrypt PHP z poleceniami PostgreSQL zwracającymi NULL dla danych JSon

  5. Postgis / Geodjango:Nie można określić wersji PostGIS dla bazy danych