2014-09-22 16 views
5

In einer Postgres 9.3-Datenbank habe ich eine Tabelle, in der eine Spalte JSON enthält, wie in der Testtabelle im Beispiel unten gezeigt.Postgres: Erweitern Sie JSON-Spalte in Zeilen

test=# create table things (id serial PRIMARY KEY, details json, other_field text); 
CREATE TABLE 
test=# \d things 
          Table "public.things" 
    Column | Type |      Modifiers 
-------------+---------+----------------------------------------------------- 
id   | integer | not null default nextval('things_id_seq'::regclass) 
details  | json | 
other_field | text | 
Indexes: 
    "things_pkey" PRIMARY KEY, btree (id) 

test=# insert into things (details, other_field) 
     values ('[{"json1": 123, "json2": 456},{"json1": 124, "json2": 457}]', 'nonsense'); 
INSERT 0 1 
test=# insert into things (details, other_field) 
     values ('[{"json1": 234, "json2": 567}]', 'piffle'); 
INSERT 0 1 
test=# select * from things; 
id |       details       | other_field 
----+-------------------------------------------------------------+------------- 
    1 | [{"json1": 123, "json2": 456},{"json1": 124, "json2": 457}] | nonsense 
    2 | [{"json1": 234, "json2": 567}]        | piffle 
(2 rows) 

Der JSON ist immer ein Array mit einer variablen Anzahl von Hashes. Jeder Hash hat immer den gleichen Schlüsselsatz. Ich versuche, eine Abfrage zu schreiben, die eine Zeile für jeden Eintrag im JSON-Array zurückgibt, mit Spalten für jeden Hash-Schlüssel und die ID aus der Tabelle diens. Ich hoffe auf eine Ausgabe wie die folgende:

thing_id | json1 | json2 
----------+-------+------- 
     1 | 123 | 456 
     1 | 124 | 457 
     2 | 234 | 567 

das heißt zwei Zeilen für Einträge mit zwei Elementen in der JSON-Array. Ist es möglich, Postgres dazu zu bringen? json_populate_recordset fühlt sich an wie ein wesentlicher Teil der Antwort, aber ich kann es nicht mit mehr als einer Zeile gleichzeitig arbeiten.

Antwort

6
select id, 
    (details ->> 'json1')::int as json1, 
    (details ->> 'json2')::int as json2 
from (
    select id, json_array_elements(details) as details 
    from things 
) s 
; 
id | json1 | json2 
----+-------+------- 
    1 | 123 | 456 
    1 | 124 | 457 
    2 | 234 | 567 
Verwandte Themen