我有一张表:
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
答案 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.
}
}
答案 1 :(得分:0)
假设您的jsonb
数组始终包含问题中给出的两个元素,您可以明确选择所有必需元素:
SELECT id, other, (attributes->0)->>'value' AS a, (attributes->1)->>'value' AS b
FROM myrecord;