将json结构转换为行

时间:2016-03-25 15:33:49

标签: json postgresql

我有一张表:

CREATE TABLE myrecord AS
id INT
other TEXT
attributes JSONB

属性的结构如下:

[
   {"name": "a", "value": "1"},
   {"name": "b", "value": "2"}
]

我希望将其转换为以下结果:

id INT, other TEXT, a TEXT, b TEXT

对于像

这样的给定行
1 | "foo" | {..as above..}

我得到的结果如

1 | "foo" | "1" | "2"

现在我可以像这样解压缩属性结构:

CREATE TYPE myrecord_attributes AS (name TEXT, value TEXT);

SELECT
   id,
   other,
   (json_populate_recordset(NULL :: myrecord_attributes,
                            attributes :: JSON)).*
FROM myrecord

但是我得到的结果如下:

1 | "foo" | "a" | "1"
1 | "foo" | "b" | "2"

如何将json_populate_recordset的结果展平到适当的结构中?我也对替代解决方案持开放态度,完全没有这样的解决方案。

如果重要的话,我会使用postgres 9.4

2 个答案:

答案 0 :(得分:3)

你可以这样做:

->>

如果您希望使用双引号返回值,只需将->更改为select m.id, m.other, max(case when x.value::json->>'name' = 'a' then x.value::json->>'value' else '' end) as a, max(case when x.value::json->>'name' = 'b' then x.value::json->>'value' else '' end) as b from myrecord m, json_array_elements(m.attributes) x group by m.id, m.other;

在此处查看:http://sqlfiddle.com/#!15/450cc/9

这是在Postgres 9.3或更高版本中使用隐式LATERAL JOIN

修改

我的第一个解决方案不符合OP的要求,因此,我创建了另一个解决方案:

StringBuilder builder = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
    String line;
    while ((line = br.readLine()) != null) {
    builder.append(line);
    // process the line.
    }
}

在此处查看:http://sqlfiddle.com/#!15/450cc/14

答案 1 :(得分:0)

假设您的jsonb数组始终包含问题中给出的两个元素,您可以明确选择所有必需元素:

SELECT id, other, (attributes->0)->>'value' AS a, (attributes->1)->>'value' AS b
FROM myrecord;