#sql #postgresql #jsonb
Вопрос:
Я новичок в Postgres. Я хочу удалить объект JSON из массива JSON.
У меня есть таблица, в которой я использую столбец jsonb, в котором я сохраняю массив JSON, как показано ниже.
[
{
"id": "c75e7a-001e-4d64-9613-62f666d42103",
"name": "Product1"
},
{
"id": "c75e7a-001e-4d64-9613-62f666d42103",
"name": null
},
{
"id": "c75e7a-001e-4d64-9613-62f666d42103",
"name": "Product2"
},
{
"id": "c75e7a-001e-4d64-9613-62f666d42103",
"name": null
}
]
Я хочу удалить объекты JSON из массива, который содержит нулевое значение в ключе name.
после удаления ответ должен быть таким
[
{
"id": "c75e7a-001e-4d64-9613-62f666d42103",
"name": "Product1"
},
{
"id": "c75e7a-001e-4d64-9613-62f666d42103",
"name": "Product2"
}
]
кто-нибудь, пожалуйста, помогите мне написать SQL-запрос,
Я знаю, как получить все записи из таблицы, которая содержит нулевое значение.
SELECT *
FROM table_name
WHERE jsonb_col_name @>CAST('[{"name": null}]' AS JSONB);
Но я не знаю, как сделать запрос на удаление, пожалуйста, помогите мне с этим.
Как я могу это сделать с помощью запроса?
Ответ №1:
Отмените массив с jsonb_array_elements
помощью, исключите null
значения с помощью a FILTER
и снова объедините их, например
SELECT
jsonb_agg(j) FILTER (WHERE j->>'name' IS NOT NULL)
FROM table_name t, jsonb_array_elements(jsonb_col) j
GROUP BY t.jsonb_col;
ДЕМОНСТРАЦИЯ: db<>fiddle
Ответ №2:
Вы можете отфильтровать j.value ->> 'name' IS NOT NULL
после разделения массива на подобъекты с помощью JSONB_ARRAY_ELEMENTS
, а затем применить JSONB_AGG
, чтобы преобразовать его обратно в массив, например
SELECT JSONB_PRETTY(
JSONB_AGG(j)
)
FROM t,
JSONB_ARRAY_ELEMENTS(json_data) AS j
WHERE j.value ->> 'name' IS NOT NULL
GROUP BY json_data
Если необходимо обновить существующие данные, вы можете рассмотреть возможность использования
WITH tt AS
(
SELECT JSONB_AGG(j) AS new_val,
json_data
FROM t,
JSONB_ARRAY_ELEMENTS(json_data) AS j
WHERE j.value ->> 'name' IS NOT NULL
GROUP BY json_data
)
UPDATE t
SET json_data = new_val::JSONB
FROM tt
WHERE t.json_data = tt.json_data
Ответ №3:
Вы можете использовать json_array_elements
:
select json_agg(i.value) from json_array_elements('[{"id": "c75e7a-001e-4d64-9613-62f666d42103", "name": "Product1"}, {"id": "c75e7a-001e-4d64-9613-62f666d42103", "name": null}, {"id": "c75e7a-001e-4d64-9613-62f666d42103", "name": "Product2"}, {"id": "c75e7a-001e-4d64-9613-62f666d42103", "name": null}]') v
where (v.value -> 'name')::text != 'null'
Вывод:
[{"id": "c75e7a-001e-4d64-9613-62f666d42103", "name": "Product1"}, {"id": "c75e7a-001e-4d64-9613-62f666d42103", "name": "Product2"}]