来自 json 列的 Postgres select 特定嵌套键
Postgres select specific nested keys from json column
有一个 table 和 json
列,这个 json 相当大,所以我只想 filter/select 特定的嵌套键。
Json 示例:
{
"title":{
"nested_1":"This is nested key 1",
"nested_2":"This is nested key 2",
"nested_3":"This is nested key 3",
"nested_4":"This is nested key 4",
"nested_5":"This is nested key 5"
},
"description":{
"nested_1":"This is nested key 1",
"nested_2":"This is nested key 2",
"nested_3":"This is nested key 3",
"nested_4":"This is nested key 4",
"nested_5":"This is nested key 5"
},
"meta":{
"nested_1":"This is nested key 1",
"nested_2":"This is nested key 2",
"nested_3":"This is nested key 3",
"nested_4":"This is nested key 4",
"nested_5":"This is nested key 5"
}
}
例如,我只想 select nested_3
和 nested_5
(但保留 json
结构):
{
"title":{
"nested_3":"This is nested key 3",
"nested_5":"This is nested key 5"
},
"description":{
"nested_3":"This is nested key 3",
"nested_5":"This is nested key 5"
},
"meta":{
"nested_3":"This is nested key 3",
"nested_5":"This is nested key 5"
}
}
到目前为止我尝试了什么:
select
id,
(select json_object_agg(key, val) from (
values
('nested_3', (select json_object_agg(t.token, t.content->'nested_3') from json_each(json_col) as t(token, content))),
('nested_5', (select json_object_agg(t.token, t.content->'nested_5') from json_each(json_col) as t(token, content)))
) as foo(key, val)) as json_col
from my_table
这是可行的,但给出了相反的结果(符合逻辑,基于上述查询):
{
"nested_3": {
"title": "This is nested key 3",
"description": "This is nested key 3",
"meta": "This is nested key 3"
},
"nested_5": {
"title": "This is nested key 5",
"description": "This is nested key 5",
"meta": "This is nested key 5"
}
}
我也试过嵌套:
(select json_object_agg(t.token, json_object_agg(t.content->'nested_3', t.languages->'nested_5')) from json_each(json_col) as t(token, content))
但这给了我一个错误:aggregate function calls cannot be nested
有一种方法可以 select 仅特定的嵌套键但保留 json 结构吗?
Postgres 版本:12
找到了一种方法:使用 json_build_object
那么在每个循环中 json_each
中发生的事情我们只需要 keys/value 创建新对象,并且在使用 json_object_agg
将其推送到我们的输出后如果密钥已经存在将推送到以前的对象,否则将创建新密钥。
select
id,
(
select
json_object_agg(t.token, json_build_object('nested_3', t.content->'nested_3', 'nested_5', t.content->'nested_5'))
from json_each(json_col) as t(token, content)
) as json_col
from my_table
如果有人有更好的解决方案或者更好的描述解释,请post您的回答。
使用声明的而不是硬编码的键列表,in ('nested_3', 'nested_5')
。
select id, (
select jsonb_object_agg(key, (
select jsonb_object_agg(key, value)
from jsonb_each(t.value)
where key in ('nested_3', 'nested_5')
)) json_filtered
from jsonb_each(jsonfield) t
) from the_table;
有一个 table 和 json
列,这个 json 相当大,所以我只想 filter/select 特定的嵌套键。
Json 示例:
{
"title":{
"nested_1":"This is nested key 1",
"nested_2":"This is nested key 2",
"nested_3":"This is nested key 3",
"nested_4":"This is nested key 4",
"nested_5":"This is nested key 5"
},
"description":{
"nested_1":"This is nested key 1",
"nested_2":"This is nested key 2",
"nested_3":"This is nested key 3",
"nested_4":"This is nested key 4",
"nested_5":"This is nested key 5"
},
"meta":{
"nested_1":"This is nested key 1",
"nested_2":"This is nested key 2",
"nested_3":"This is nested key 3",
"nested_4":"This is nested key 4",
"nested_5":"This is nested key 5"
}
}
例如,我只想 select nested_3
和 nested_5
(但保留 json
结构):
{
"title":{
"nested_3":"This is nested key 3",
"nested_5":"This is nested key 5"
},
"description":{
"nested_3":"This is nested key 3",
"nested_5":"This is nested key 5"
},
"meta":{
"nested_3":"This is nested key 3",
"nested_5":"This is nested key 5"
}
}
到目前为止我尝试了什么:
select
id,
(select json_object_agg(key, val) from (
values
('nested_3', (select json_object_agg(t.token, t.content->'nested_3') from json_each(json_col) as t(token, content))),
('nested_5', (select json_object_agg(t.token, t.content->'nested_5') from json_each(json_col) as t(token, content)))
) as foo(key, val)) as json_col
from my_table
这是可行的,但给出了相反的结果(符合逻辑,基于上述查询):
{
"nested_3": {
"title": "This is nested key 3",
"description": "This is nested key 3",
"meta": "This is nested key 3"
},
"nested_5": {
"title": "This is nested key 5",
"description": "This is nested key 5",
"meta": "This is nested key 5"
}
}
我也试过嵌套:
(select json_object_agg(t.token, json_object_agg(t.content->'nested_3', t.languages->'nested_5')) from json_each(json_col) as t(token, content))
但这给了我一个错误:aggregate function calls cannot be nested
有一种方法可以 select 仅特定的嵌套键但保留 json 结构吗?
Postgres 版本:12
找到了一种方法:使用 json_build_object
那么在每个循环中 json_each
中发生的事情我们只需要 keys/value 创建新对象,并且在使用 json_object_agg
将其推送到我们的输出后如果密钥已经存在将推送到以前的对象,否则将创建新密钥。
select
id,
(
select
json_object_agg(t.token, json_build_object('nested_3', t.content->'nested_3', 'nested_5', t.content->'nested_5'))
from json_each(json_col) as t(token, content)
) as json_col
from my_table
如果有人有更好的解决方案或者更好的描述解释,请post您的回答。
使用声明的而不是硬编码的键列表,in ('nested_3', 'nested_5')
。
select id, (
select jsonb_object_agg(key, (
select jsonb_object_agg(key, value)
from jsonb_each(t.value)
where key in ('nested_3', 'nested_5')
)) json_filtered
from jsonb_each(jsonfield) t
) from the_table;