在 Postgresql Jsonb 中将字符串数组转换为 Json 对象数组
Convert array of string to array of Json objects in Postgresql Jsonb
我有一个 jsonb 栏像
{
"foo":{"bar" :["b","c","d"]}
}
我想将 "bar" 数组的所有项转换为具有 "name" 键的 json 结果应为:
{
"foo":{"bar" :[{"name":"b"},{"name":"c"},{"name":"d"}]}
}
我希望在 table.
的所有行中使用 postgresql 查询来做到这一点
我尝试了各种查询和函数,但我的主要问题是包装部分字符串。
提供提示和帮助
假设您使用的是支持 JSON 的 Postgres 版本 (9.4+),这应该让您接近:
WITH cte(myJSON) AS (
SELECT CAST('{"foo":{"bar" :["b","c","d"]}}'AS JSONB) AS MyJSON
UNION ALL
SELECT CAST('{"foo":{"bar" :["e","f","g"]}}'AS JSONB) AS MyJSON
)
SELECT
JSON_AGG(
(SELECT ROW_TO_JSON(_) FROM (SELECT name) AS _)
) myrow
FROM (
SELECT JSONB_ARRAY_ELEMENTS(myjson->'foo'->'bar') AS name,
ROW_NUMBER() OVER() AS RowNum
FROM cte
) src
GROUP BY src.RowNum
这将 return [{"name":"b"},{"name":"c"},{"name":"d"}]
。
然后您可以根据需要构建最终的 JSON
。
更新
这非常 hacky,我确信有更简洁的方法,但我更新了上面的查询以处理多行。只需将 CTE
引用替换为您的实际 table 名称,并将 myjson
替换为您的 JSON
列的名称。
输出:
[{"name":"b"},{"name":"c"},{"name":"d"}]
[{"name":"e"},{"name":"f"},{"name":"g"}]
如果可行,请告诉我。
更新更新
这是您可以使用的 UPDATE
语句:
UPDATE t1 tgt
SET jsoncol = JSONB_SET(
jsoncol, -- Source JSON
'{foo,bar}', -- Target node to update
src.new_json -- New value
)
FROM (
SELECT
ID,
JSONB_AGG(
(SELECT TO_JSONB(_) FROM (SELECT name) AS _) -- Convert new row to JSON
) new_json
FROM (
SELECT
ID,
JSONB_ARRAY_ELEMENTS(jsoncol->'foo'->'bar') AS name -- Convert array to rows
FROM t1
) src
GROUP BY src.ID
) src
WHERE tgt.ID = src.ID -- Update "tgt" table with rows from "src" table
;
我有一个 jsonb 栏像
{
"foo":{"bar" :["b","c","d"]}
}
我想将 "bar" 数组的所有项转换为具有 "name" 键的 json 结果应为:
{
"foo":{"bar" :[{"name":"b"},{"name":"c"},{"name":"d"}]}
}
我希望在 table.
的所有行中使用 postgresql 查询来做到这一点我尝试了各种查询和函数,但我的主要问题是包装部分字符串。
提供提示和帮助
假设您使用的是支持 JSON 的 Postgres 版本 (9.4+),这应该让您接近:
WITH cte(myJSON) AS (
SELECT CAST('{"foo":{"bar" :["b","c","d"]}}'AS JSONB) AS MyJSON
UNION ALL
SELECT CAST('{"foo":{"bar" :["e","f","g"]}}'AS JSONB) AS MyJSON
)
SELECT
JSON_AGG(
(SELECT ROW_TO_JSON(_) FROM (SELECT name) AS _)
) myrow
FROM (
SELECT JSONB_ARRAY_ELEMENTS(myjson->'foo'->'bar') AS name,
ROW_NUMBER() OVER() AS RowNum
FROM cte
) src
GROUP BY src.RowNum
这将 return [{"name":"b"},{"name":"c"},{"name":"d"}]
。
然后您可以根据需要构建最终的 JSON
。
更新
这非常 hacky,我确信有更简洁的方法,但我更新了上面的查询以处理多行。只需将 CTE
引用替换为您的实际 table 名称,并将 myjson
替换为您的 JSON
列的名称。
输出:
[{"name":"b"},{"name":"c"},{"name":"d"}]
[{"name":"e"},{"name":"f"},{"name":"g"}]
如果可行,请告诉我。
更新更新
这是您可以使用的 UPDATE
语句:
UPDATE t1 tgt
SET jsoncol = JSONB_SET(
jsoncol, -- Source JSON
'{foo,bar}', -- Target node to update
src.new_json -- New value
)
FROM (
SELECT
ID,
JSONB_AGG(
(SELECT TO_JSONB(_) FROM (SELECT name) AS _) -- Convert new row to JSON
) new_json
FROM (
SELECT
ID,
JSONB_ARRAY_ELEMENTS(jsoncol->'foo'->'bar') AS name -- Convert array to rows
FROM t1
) src
GROUP BY src.ID
) src
WHERE tgt.ID = src.ID -- Update "tgt" table with rows from "src" table
;