PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

rekurencyjnie spłaszcz zagnieżdżony jsonb w postgresie bez nieznanej głębokości i nieznanych pól kluczowych

Przykładowa konfiguracja:

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

Zapytanie rekurencyjne wykonuje jsonb_each() dla każdego obiektu json znalezionego na dowolnym poziomie. Nowe nazwy kluczy zawierają pełną ścieżkę od katalogu głównego:

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)

Jeśli chcesz uzyskać płaski widok tych danych, możesz użyć funkcji create_jsonb_flat_view() opisane w tej odpowiedzi Spłaszczyć zagregowane pary klucz/wartość z pola JSONB?

Musisz utworzyć tabelę (lub widok) ze spłaszczonym 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()

Teraz możesz użyć funkcji na stole:

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)

Rozwiązanie działa w Postgresie 9.5+, ponieważ wykorzystuje wprowadzoną w tej wersji funkcję jsonb. Jeśli twoja wersja serwera jest starsza, zdecydowanie zaleca się uaktualnienie Postgresa, aby efektywnie korzystać z 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. sqlalchemy postgresql Is Null index

  2. Moje ulubione rozszerzenia PostgreSQL — część druga

  3. Jak usunąć dane z wielu tabel?

  4. Wymień wszystkie nazwy indeksów, nazwy kolumn i ich nazwę tabeli bazy danych PostgreSQL

  5. Jak przekonwertować pole znacznika czasu na ciąg ISO 8601 w danej strefie czasowej?