PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Chèn mục mới vào cột JSONB dựa trên giá trị của trường khác - postgres

Đây phải là đủ thông tin để hoàn thành truy vấn:

Hãy tạo dữ liệu giả

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
      }
    ]
  }
]');

Bây giờ hãy bùng nổ mảng bằng cách sử dụng jsonb_array_elements với thứ tự để lấy chỉ mục và thuộc tính

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);

Kết quả của truy vấn này là:

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

Ở đó, bạn có thông tin cần thiết để tìm nạp các phần tử phụ mà bạn cần, cũng như tất cả các chỉ mục mà bạn cần cho truy vấn của mình.

Bây giờ, đến lần chỉnh sửa cuối cùng, bạn đã có truy vấn mà bạn muốn:

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}]}';

Tại nơi bạn sẽ sử dụng id, vì đó là những hàng mà bạn quan tâm và trong các chỉ mục bạn lấy chúng từ truy vấn. Vì vậy:

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;

Như bạn có thể thấy, điều này rất khó chịu.

Tôi khuyên bạn nên sử dụng một cách tiếp cận sql hơn, nghĩa là có các tính năng trong một bảng thay vì bên trong một json, một liên kết fk với bảng của bạn ... Nếu bạn thực sự cần sử dụng json, chẳng hạn như vì tên miền thực sự phức tạp và được xác định ở cấp độ ứng dụng và rất linh hoạt. Sau đó, tôi khuyên bạn nên thực hiện cập nhật bên trong mã ứng dụng




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thêm năm vào một ngày trong PostgreSQL

  2. Làm cách nào để thay đổi ID bảng từ nối tiếp sang danh tính?

  3. Sử dụng quy tắc để chèn vào chuỗi tự động tăng dần bảng phụ

  4. sails.js Truy vấn kế hoạch chi tiết theo quan hệ

  5. Làm cách nào để đặt lại chuỗi khóa chính của postgres khi nó không đồng bộ?