简体   繁体   English

Postgres:将 JSON 列展开为行

[英]Postgres: Expand JSON column into rows

In a Postgres 9.3 database I have a table in which one column contains JSON, as in the test table shown in the example below.在 Postgres 9.3 数据库中,我有一个表,其中一列包含 JSON,如下例所示的测试表所示。

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)

The JSON is always an array containing a variable number of hashes. JSON 始终是一个包含可变数量哈希的数组。 Each hash always has the same set of keys.每个散列始终具有相同的键集。 I am trying to write a query which returns a row for each entry in the JSON array, with columns for each hash key and the id from the things table.我正在尝试编写一个查询,它为 JSON 数组中的每个条目返回一行,每个哈希键的列和 things 表中的 id。 I'm hoping for output like the following:我希望输出如下:

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

ie two rows for entries with two items in the JSON array.即 JSON 数组中包含两个项目的条目的两行。 Is it possible to get Postgres to do this?是否有可能让 Postgres 做到这一点? json_populate_recordset feels like an essential part of the answer, but I can't get it to work with more than one row at once. json_populate_recordset感觉像是答案的重要组成部分,但我不能让它一次处理超过一行。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM