2017-05-11 1 views
3

말, JSONB 열이있는 json_table 테이블이 있습니다. 이 칼럼의 각 요소는 PostgreSQL 9.6에서는 간단한 JSON dicts로 채워진 JSONB 열을 확장하는 가장 간단한 방법은 무엇입니까?

{'first_field': 2 , 'second_field': 42} 

은 dicts 컬럼으로 설정되어 있었다 새 테이블을 만들 수있는 방법이 있습니까, 예를 들어, 하나의 단순한 딕셔너리입니까?

CREATE TABLE normal_table ... first_field, second_field ... etc; 
INSERT INTO normal_table (
    id, 
    first_field, 
    second_field, 
    ... 
) 
SELECT 
    id, 
    json_field->>'first_field', 
    json_field->>'second_field', 
    ... 
FROM json_table; 

다음과 같은 일을 할 수있는 방법이 있나요 : 다음과 같이

내 현재의 접근 방식은 무엇입니까?

SELECT 
    id, 
    expand_json_dict(json_field) 
FROM json_table; 

또는 유사한 간결한 방법으로 수행 할 수 있습니까? JSONB 열에는 확장하려는 많은 필드가 있으며 쿼리가 다루기 힘들어집니다. 나는 실제로 생성/삽입 스크립트를 생성하는 파이썬 함수를 만들었습니다. 그래도 PostgreSQL으로 할 수있는 좋은 방법이 있기를 바랍니다.

의견이 있으십니까?

편집

다음 여기서 피드백에 기초하여 작동 용액이다. 고마워. 유형에 존재하지 않는 JSON 문서의 키가있는 경우

create type my_type as (first_field varchar, second_field varchar); 

SELECT id, (json_populate_record(null::my_type, json_field)).* 
FROM json_table; 

, 그들은 단순히 :

drop table if exists json_table; 
create table json_table (
    id int, 
    json_field jsonb 
); 
insert into json_table VALUES 
    (2, ('{"second_field": 43, "first_field": 3}'::jsonb)), 
    (1, ('{"first_field": 2 , "second_field": 42}'::jsonb)); 

drop table if exists normal_table; 
create table normal_table (
    id int, 
    first_field int, 
    second_field int 
); 

insert into normal_table 
select (
    jsonb_populate_record(
     null::normal_table, 
     jsonb_set(json_field, '{id}', id::text::jsonb) 
    ) 
).* 
from json_table; 

select * from normal_table; 
그런 다음 열쇠를 반영하는 유형 (기록)을 생성 할 수 있습니다
+0

버전 ? –

+0

postgres 버전은 9.6입니다. –

+0

''json_populate_recordset' 또는'json_each_text'와 같이 사용합니다. –

답변

2

jsonb_populate_record 함수에 기본 유형으로 normal_table 유형을 사용 : id를 생성하는

create table normal_table (
    id int, 
    first_field int, 
    second_field int 
); 

with json_table (json_field) as (values 
    ('{"first_field": 2 , "second_field": 42}'::jsonb) 
) 
select (jsonb_populate_record(null::normal_table, json_field)).* 
from json_table 
; 
id | first_field | second_field                                   
----+-------------+--------------                                   
    |   2 |   42 

가 필요한 경우 삽입 할 사용 jsonb_set : 당신이 실행 포스트 그레스의

with json_table (json_field) as (values 
    ('{"first_field": 2 , "second_field": 42}'::jsonb), 
    ('{"first_field": 5 , "second_field": 1}') 
) 
select (
    jsonb_populate_record(
     null::normal_table, 
     jsonb_set(json_field, '{id}', (row_number() over())::text::jsonb) 
    ) 
).* 
from json_table 
; 
id | first_field | second_field 
----+-------------+-------------- 
    1 |   2 |   42 
    2 |   5 |   1 
+0

을 참조 할 테이블이 가장 좋은 답변입니다. 그러나 나는 '함께'부분에 대해 잘 모르겠습니다. 왜 그곳에 있습니까? 방금 제거하고 모든 것이 바뀌 었습니다. –

+0

@ AndréChristofferAndersen CTE, 공통 테이블 식입니다. 실제 테이블 대신에 가져올 샘플 테이블을 가지고 있습니다. –

+0

괜찮습니다. 감사. 그리고 'id'를 포함하는 최종 변경 사항은 완벽했습니다. 감사. –

0

json_populate_record 사용 무시. JSON 문서에서 일치하지 않는 필드가 유형 정의에있는 경우 null이됩니다.

관련 문제