Postgres JSONB Редактирование столбцов - PullRequest
1 голос
/ 25 мая 2020

Я просматривал документацию Postgres Jsonb, но не смог найти решение небольшой проблемы, которая у меня возникла.

У меня есть таблица: MY_TABLE

, которая имеет следующие столбцы:

Пользователь, Имя, Данные и Покупки

Следует отметить, что «Данные» - это jsonb и имеет несколько полей. Одно из полей внутри «данных» - это «атрибут», но значения, которые он может содержать, не синхронизированы c. Я имею в виду, что это может быть строка, список строк, пустой список или просто пустая строка. Однако я хочу это изменить.

Единственные значения, которые я хочу разрешить, - это список строк и пустой список. Я хочу преобразовать все пустые строки в пустые списки, а обычные строки в список строк.

Я пробовал использовать json_build_array, но мне не повезло

Так, например, я бы хочу, чтобы мой последний jsonb выглядел так:

       [{
           "Id": 1,
           "Attributes": ["Test"]

       },
       {
           "Id": 2,
           "Attributes": []

       },
{
           "Id": 3,
           "Attributes": []

       }]

при преобразовании из

    {
        "Id": 1,
        "Attributes": "Test"

    },
{
           "Id": 2,
           "Attributes": ""

       },
{
           "Id": 3,
           "Attributes": []

       }
]

Меня интересует только поле «Атрибуты» внутри Json, а не другие поля.

Я также хочу, чтобы для некоторых атрибутов с пустой строкой «Attributes»: «» они отображались в пустой список, а не в список с пустой строкой ([] not [» "])

Я также хочу сохранить значения пустого массива ([]) для атрибутов, которые уже содержат пустое значение массива.

Это то, что у меня есть:

jsonb_set(
    mycol,
    '{Attributes}',
    case when js ->> 'Attributes' <> '' 
        then jsonb_build_array(js ->> 'Attributes')
        else '[]'::jsonb
    end
)

Однако Атрибуты: [] сопоставляются с ["[]"]

1 Ответ

0 голосов
/ 25 мая 2020

Используйте jsonb_array_elements() для перебора элементов каждой ячейки «данных» и jsonb_agg для перегруппировки значений преобразования в массив:

WITH test_data(js) AS (
    VALUES ($$ [
      {
        "Id": 1,
        "Attributes": "Test"
      },
      {
        "Id": 2,
        "Attributes": ""
      },
      {
        "Id": 3,
        "Attributes": []
      }
    ]
    $$::JSONB)
)
SELECT transformed_elem
FROM test_data
JOIN LATERAL (
    SELECT jsonb_agg(jsonb_set(
            elem,
            '{Attributes}',
            CASE
                WHEN elem -> 'Attributes' IN ('""', '[]')          THEN '[]'::JSONB
                WHEN jsonb_typeof(elem -> 'Attributes') = 'string' THEN jsonb_build_array(elem -> 'Attributes')
                ELSE elem -> 'Attributes'
            END
        )) AS transformed_elem
    FROM jsonb_array_elements(test_data.js) AS f(elem) -- iterate over every element in the array
) s
 ON TRUE

возвращает

[{"Id": 1, "Attributes": ["Test"]}, {"Id": 2, "Attributes": []}, {"Id": 3, "Attributes": []}]
...