sql >> Database teknologi >  >> RDS >> PostgreSQL

Rekursiv JSONB postgres

Jeg har brugt denne eksempeltabel til at gøre forespørgslen mere læsbar:

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

Du skal tilslutte dig både jsonb_each(value) og jsonb_array_elements(value) betinget, afhængigt af typen af ​​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;
 

Output:

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)

Elementer af json-arrays har ingen nøgler, vi bør bruge deres indekser til at bygge en sti. Derfor funktionen jsonb_array_elements() skal kaldes med ordinalitet. Ifølge dokumentationen (se 7.2.1.4. Tabelfunktioner ):

Funktionskaldet

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

returnerer par (value, ordinality) aliaseret som (arr_value, arr_key) .




  1. NoSQL:liv uden et skema

  2. SYSDATE-funktion i Oracle

  3. Eksempel på SQL Servers sys.dm_sql_referenced_entities() Returnerer en enhed, der refererer til en linket server

  4. Sådan finder du hvornår MySQL/MariaDB-serveren blev startet