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

不明な深さと不明なキーフィールドなしで、postgresでネストされたjsonbを再帰的にフラット化します

    セットアップ例:

    create table my_table(id int, data jsonb);
    insert into my_table values
    (1,
    $${
       "type": "a type",
       "form": "a form",
       "contact": {
           "name": "a name",
           "phone": "123-456-78",
           "type": "contact type",
           "parent": {
               "id": "444",
               "type": "parent type" 
               } 
        }
    }$$);
    

    再帰クエリはjsonb_each()を実行します 任意のレベルで見つかったすべてのjsonオブジェクトに対して。新しいキー名には、ルートからのフルパスが含まれています:

    with recursive flat (id, key, value) as (
        select id, key, value
        from my_table,
        jsonb_each(data)
    union
        select f.id, concat(f.key, '.', j.key), j.value
        from flat f,
        jsonb_each(f.value) j
        where jsonb_typeof(f.value) = 'object'
    )
    select id, jsonb_pretty(jsonb_object_agg(key, value)) as data
    from flat
    where jsonb_typeof(value) <> 'object'
    group by id;
    
     id |                   data                   
    ----+------------------------------------------
      1 | {                                       +
        |     "form": "a form",                   +
        |     "type": "a type",                   +
        |     "contact.name": "a name",           +
        |     "contact.type": "contact type",     +
        |     "contact.phone": "123-456-78",      +
        |     "contact.parent.id": "444",         +
        |     "contact.parent.type": "parent type"+
        | }
    (1 row)
    

    このデータのフラットビューを取得したい場合は、関数create_jsonb_flat_view()を使用できます。 この回答で説明されている JSONBフィールドからのフラットに集約されたキー/値ペア?

    フラット化されたjsonbを使用してテーブル(またはビュー)を作成する必要があります:

    create table my_table_flat as 
    -- create view my_table_flat as 
    with recursive flat (id, key, value) as (
    -- etc as above
    -- but without jsonb_pretty()
    

    これで、テーブルの関数を使用できます:

    select create_jsonb_flat_view('my_table_flat', 'id', 'data');
    
    select * from my_table_flat_view;
    
    
     id | contact.name | contact.parent.id | contact.parent.type | contact.phone | contact.type |  form  |  type  
    ----+--------------+-------------------+---------------------+---------------+--------------+--------+--------
      1 | a name       | 444               | parent type         | 123-456-78    | contact type | a form | a type
    (1 row)
    

    このバージョンで導入されたjsonb関数を使用するため、このソリューションはPostgres9.5以降で機能します。サーバーのバージョンが古い場合は、jsonbを効率的に使用するためにとにかくPostgresをアップグレードすることを強くお勧めします。




    1. java.sql.SQLExceptionパラメータインデックスが範囲外です(1>パラメータの数。0)

    2. MySQL Create Table as SELECT

    3. SQL Server 2005で大文字と小文字を区別するように変更するにはどうすればよいですか?

    4. Docker Compose + Postgres:ポートを公開します