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. SQLLIKE句でのSqlParameterの使用が機能しない

    2. PostgreSQLJDBCを使用した接続プール

    3. RAISERROR() の構文の意味は何ですか?

    4. PostgreSQLMAXおよびGROUPBY