Thiết lập mẫu:
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"
}
}
}$$);
Truy vấn đệ quy thực thi jsonb_each()
cho mọi đối tượng json được tìm thấy ở bất kỳ cấp độ nào. Các tên khóa mới chứa đầy đủ đường dẫn từ gốc:
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)
Nếu bạn muốn xem dữ liệu này một cách phẳng, bạn có thể sử dụng hàm create_jsonb_flat_view()
được mô tả trong câu trả lời này Làm phẳng các cặp khóa / giá trị tổng hợp khỏi trường JSONB?
Bạn cần tạo một bảng (hoặc chế độ xem) với jsonb phẳng:
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()
Bây giờ bạn có thể sử dụng hàm trên bảng:
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)
Giải pháp hoạt động trong Postgres 9.5+, vì nó sử dụng hàm jsonb được giới thiệu trong phiên bản này. Nếu phiên bản máy chủ của bạn cũ hơn, bạn nên nâng cấp Postgres để sử dụng jsonb một cách hiệu quả.