从Postgres中的json对象中提取键值

时间:2016-08-18 05:34:25

标签: json postgresql jsonb

我有一个Postgres表,其内容与此类似:

id  | data

1   | {"a":"4", "b":"5"}
2   | {"a":"6", "b":"7"}
3   | {"a":"8", "b":"9"}

第一列是整数,第二列是json列。

我希望能够扩展json中的键和值,因此结果如下所示:

id  | key  | value

1   | a    | 4
1   | b    | 5
2   | a    | 6
2   | b    | 7
3   | a    | 8
3   | b    | 9

这可以在Postgres SQL中实现吗?

我尝试了什么

鉴于原始表可以这样模拟:

select *
from 
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)

我可以使用以下方式获取密钥:

select id, json_object_keys(data::json)
from 
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)

我可以将它们作为这样的记录集来获取:

select id, json_each(data::json)
from 
(
values
(1, '{"a":"4", "b":"5"}'::json),
(2, '{"a":"6", "b":"7"}'::json),
(3, '{"a":"8", "b":"9"}'::json)
) as q (id, data)

但我无法弄清楚如何用id,key和value来实现结果。

有什么想法吗?

注意:我使用的真正的json比这更嵌套,但我认为这个例子很好地代表了我的潜在问题。

3 个答案:

答案 0 :(得分:17)

SELECT q.id, d.key, d.value
FROM q
JOIN json_each_text(q.data) d ON true
ORDER BY 1, 2;

函数json_each_text()是一个集合返回函数,因此您应该将其用作行源。该函数的输出位于表q的{​​{3}},这意味着对于表中的每一行,(key, value)列中的每个data对仅连接到因此,行保持原始行与json对象形成的行之间的关系。

q也可以是一个非常复杂的子查询(或VALUES子句,就像你的问题一样)。在函数中,从评估该子查询的结果中使用适当的列,因此您只使用对子查询的别名和子查询中的(别名)列的引用。

答案 1 :(得分:1)

当您有多个json加入时,我认为另一种很容易工作的方式是:

SELECT data -> 'key'   AS key, 
       data -> 'value' AS value 
FROM   (SELECT Hstore(Json_each_text(data)) AS data 
        FROM   "your_table") t;

答案 2 :(得分:1)

这也可以解决:

select you_table.id , js.key, js.value
from you_table, json_each(you_table.data) as js