从 Postgres 中的 json 个对象中提取键值
Extract key, value from json objects in Postgres
我有一个 Postgres table,其内容与此类似:
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?
我试过的
假设原来的table可以这样模拟:
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 嵌套明显多于此,但我认为此示例很好地代表了我的潜在问题。
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 到 table q
,这意味着对于 table 中的每一行,来自 [=14] 的每个 (key, value)
对=] 列仅连接到该行,因此保持原始行和从 json
对象形成的行之间的关系。
table q
也可以是一个非常复杂的子查询(或 VALUES
子句,就像您的问题一样)。在该函数中,从评估该子查询的结果中使用适当的列,因此您仅使用对子查询别名和子查询中列(的别名)的引用。
当你有多个 json 要加入时,我认为另一种非常容易工作的方法是做类似的事情:
SELECT data -> 'key' AS key,
data -> 'value' AS value
FROM (SELECT Hstore(Json_each_text(data)) AS data
FROM "your_table") t;
这也能解决:
select you_table.id , js.key, js.value
from you_table, json_each(you_table.data) as js
我有一个 Postgres table,其内容与此类似:
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?
我试过的
假设原来的table可以这样模拟:
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 嵌套明显多于此,但我认为此示例很好地代表了我的潜在问题。
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 到 table q
,这意味着对于 table 中的每一行,来自 [=14] 的每个 (key, value)
对=] 列仅连接到该行,因此保持原始行和从 json
对象形成的行之间的关系。
table q
也可以是一个非常复杂的子查询(或 VALUES
子句,就像您的问题一样)。在该函数中,从评估该子查询的结果中使用适当的列,因此您仅使用对子查询别名和子查询中列(的别名)的引用。
当你有多个 json 要加入时,我认为另一种非常容易工作的方法是做类似的事情:
SELECT data -> 'key' AS key,
data -> 'value' AS value
FROM (SELECT Hstore(Json_each_text(data)) AS data
FROM "your_table") t;
这也能解决:
select you_table.id , js.key, js.value
from you_table, json_each(you_table.data) as js