Предполагается, что вы используете версию Postgres с поддержкой JSON (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
Это вернет [{"name":"b"},{"name":"c"},{"name":"d"}]
.
Затем вы можете построить свой окончательный JSON
по мере необходимости.
SQL Fiddle
Ссылка
Обновление
Это очень забавно, и я уверен, что есть более чистый способ, но я обновил запрос выше, чтобы обрабатывать несколько строк.Просто замените ссылки CTE
на ваше фактическое имя таблицы, а 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
;
DB-Fiddle