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

再帰的なJSONBpostgres

    このサンプルテーブルを使用して、クエリを読みやすくしました。

    create table my_table(id serial primary key, jdata jsonb);
    insert into my_table (jdata) values
    ('{
        "key1": {
            "key2": [
                {
                    "key3": "test3",
                    "key4": "test4"
                }
            ]
        },
        "key5": [
            {
                "key6":
                [
                    {
                        "key7": "test7"
                    }
                ]
            }
        ]
    }');
    

    両方のjsonb_each(value)に参加する必要があります およびjsonb_array_elements(value) 条件付きで、valueのタイプに応じて :

    with recursive extract_all as
    (
        select 
            key as path, 
            value
        from my_table
        cross join lateral jsonb_each(jdata)
    union all
        select
            path || '.' || coalesce(obj_key, (arr_key- 1)::text),
            coalesce(obj_value, arr_value)
        from extract_all
        left join lateral 
            jsonb_each(case jsonb_typeof(value) when 'object' then value end) 
            as o(obj_key, obj_value) 
            on jsonb_typeof(value) = 'object'
        left join lateral 
            jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) 
            with ordinality as a(arr_value, arr_key)
            on jsonb_typeof(value) = 'array'
        where obj_key is not null or arr_key is not null
    )
    select *
    from extract_all;
    

    出力:

            path        |                     value                      
    --------------------+------------------------------------------------
     key1               | {"key2": [{"key3": "test3", "key4": "test4"}]}
     key5               | [{"key6": [{"key7": "test7"}]}]
     key1.key2          | [{"key3": "test3", "key4": "test4"}]
     key5.0             | {"key6": [{"key7": "test7"}]}
     key1.key2.0        | {"key3": "test3", "key4": "test4"}
     key5.0.key6        | [{"key7": "test7"}]
     key1.key2.0.key3   | "test3"
     key1.key2.0.key4   | "test4"
     key5.0.key6.0      | {"key7": "test7"}
     key5.0.key6.0.key7 | "test7"
    (10 rows)
    

    json配列の要素にはキーがないため、それらのインデックスを使用してパスを作成する必要があります。したがって、関数jsonb_array_elements() 普通に呼ばれるべきです。 ドキュメント ごと (7.2.1.4。テーブル関数を参照してください。 ):

    関数呼び出し

    jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) 
    with ordinality as a(arr_value, arr_key)
    

    ペアを返します(value, ordinality) (arr_value, arr_key)としてエイリアス 。




    1. SQL Server 2008 で XML 列をどのように読むのですか?

    2. Postgresで列を複数の行に分割する

    3. ORDER BYでCASE関数を使用するにはどうすればよいですか?

    4. MySQLとJavaで引用符文字をエスケープする方法