PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

рекурсивно изравняване на вложен jsonb в postgres без неизвестна дълбочина и неизвестни ключови полета

Примерна настройка:

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)

Решението работи в Postgres 9.5+, тъй като използва функцията jsonb, въведена в тази версия. Ако версията на вашия сървър е по-стара, силно се препоръчва да надстроите Postgres така или иначе, за да използвате jsonb ефективно.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как мога да прикача база данни към приложение в Heroku?

  2. Как изрично да прехвърляте тип литерал на масив в sqlalchemy с помощта на postgresql?

  3. PostgreSQL:ВЪНШЕН КЛЮЧ/КАСКАДА НА ИЗТРИВАНЕ

  4. Инсталиране на PL/Ruby на PostgreSQL 9.3

  5. Без диалектно съпоставяне за тип JDBC:2003