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

Вмъкнете нов елемент в колона JSONB въз основа на стойността на друго поле - postgres

Това трябва да е достатъчно информация, за да завършите заявката:

Нека създадем фиктивните данни

create table a (id serial primary key , b jsonb);

insert into a (b)
values ('[
  {
    "name": "test",
    "features": [
      {
        "name": "feature1",
        "granted": false
      },
      {
        "name": "feature2",
        "granted": true
      }
    ]
  },
  {
    "name": "another-name",
    "features": [
      {
        "name": "feature1",
        "granted": false
      },
      {
        "name": "feature2",
        "granted": true
      }
    ]
  }
]');

Сега разгънете масива с помощта на jsonb_array_elements с ординалност, за да получите индекса и свойството

select first_level.id, position, feature_position, feature
from (select a.id, arr.*
      from a,
           jsonb_array_elements(a.b) with ordinality arr (elem, position)
      where elem ->> 'name' = 'test') first_level,
     jsonb_array_elements(first_level.elem -> 'features') with ordinality features (feature, feature_position);

Резултатът от тази заявка е:

1,1,1,"{""name"": ""feature1"", ""granted"": false}"
1,1,2,"{""name"": ""feature2"", ""granted"": true}"

Там имате необходимата информация, от която се нуждаете, за да извлечете поделементите, от които се нуждаете, както и всички индекси, които са ви необходими за вашата заявка.

Сега, към окончателната редакция, вече имате заявката, която искате:

UPDATE my_table SET modules =
    jsonb_insert(my_column, '{0, features, 0}', '{"name": "newFeature", "granted": false}')
WHERE my_column ->> 'name' = 'test' AND my_column @> '{"features": [{"name":"feature1", "granted": false}]}';

В къде ще използвате id, защото това са редовете, които ви интересуват, и в индексите, които сте ги получили от заявката. И така:

UPDATE my_table SET modules =
    jsonb_insert(my_column, '{' || exploded_info.position::string || ', features, ' || exploded_info.feature_position || '}', '{"name": "newFeature", "granted": false}') from (/* previous query */) as exploded_info
WHERE exploded_info.id = my_table.id and exploded_info.feature -> 'granted' = false;

Както можете да видите, това лесно става много неприятно.

Бих препоръчал или използването на по-sql подход, тоест разполагане на функции в таблица, вместо в json, fk, свързващ това с вашата таблица... Ако наистина трябва да използвате json, например, защото домейнът е наистина сложен и дефиниран на ниво приложение и много гъвкав. Тогава бих препоръчал да правите актуализациите в кода на приложението




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. импортиране на osm файл в база данни postgres/postgis

  2. Postgres - СЪЗДАВАНЕ НА ТАБЛИЦА ОТ SELECT

  3. Грешка:не може да се определи версията на PostgreSQL от '10.3' - Django на Heroku

  4. Комитът на PostgreSQL Sqlalchemy отнема много време

  5. ГРЕШКА:не можах да осъществи достъп до файл “$libdir/plpython2” – ГРЕШКА:не можа да получи достъп до файл “$libdir/plpython3”