sql >> データベース >  >> RDS >> PostgreSQL

jsonb_set()を使用したUPDATEは、ネストされた配列内の1つのオブジェクトにのみ影響します

    説明

    FROMの副選択 UPDATEの句 3つを返します 行。ただし、ターゲットテーブルのすべての行は一度だけ更新できます。 単一のUPDATE 指図。その結果、1つの効果しか見られません。 これらの3行のうち。

    または、マニュアル

    余談ですが、サブクエリを「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. Transact-SQLの再帰CTEでUNIONではなくUNIONALLが必要なのはなぜですか。

    2. Cordaエンタープライズノード上のPostgreSQLがリレーションエラーをスローする

    3. PHPポップアップウィンドウにPOSTするクリック可能なHTMLテーブル行

    4. DLL「OraOps10.dll」を読み込めません