2016-08-18 78 views
3

JSON对象值I有一个具有内容与此类似一个Postgres表:提取密钥,从在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比这更嵌套,但我认为这个例子很好地代表了我的潜在问题。

+0

可能的重复[如何将postgresql 9.4 jsonb转换为没有函数/服务器端语言的对象](http://stackoverflow.com/questions/27181980/how-to-convert-postgresql-9-4-jsonb-to -object-without-function-server-side-langu) – e4c5

+0

使用函数'json_object_keys'或'json_each'作为表,而不是列:'select id,j.key,j.value from my_table,json_each(data)j' – Abelisto

+0

谢谢Abelisto。当然,我最终会得到一个完整的笛卡尔产品,而不是我正在寻找的表格,使用您建议的查询? –

回答

6
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()是一个返回函数集,所以您应该将它用作行来源。该函数的输出在此为joined laterally至表q,这意味着对于表中的每一行,来自data列的每个(key, value)对都只连接到该行,因此原始行与由json对象形成的行之间的关系保持。

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

+0

谢谢帕特里克。我仍然对我如何适应我原来的查询有点困惑。我使用'WITH'语句来定义'q'吗? –

+0

无需WITH语句就可以实现吗? –

+0

'q'是你所指的表,你用它作为原始表的代理。 – Patrick