#sql #postgresql #jsonb
Вопрос:
учитывая эту таблицу
родитель | полезная нагрузка |
---|---|
1 | { a: 7, b: 3 } |
2 | { a: 7, c: 3 } |
1 | { d: 3, e: 1, f: 3 } |
Я хочу обновить дочерние элементы 1
и удалить любой атрибут X
, где payload-gt;X
он есть 3
.
после выполнения запроса записи должны выглядеть следующим образом:
родитель | полезная нагрузка |
---|---|
1 | { a: 7 } |
2 | { a: 7, c: 3 } |
1 | { e: 1 } |
update records set payload=?? where parent = 1 and ??
Ответ №1:
Для этого нет встроенной функции inf, но вы можете написать свою собственную:
create function remove_keys_by_value(p_input jsonb, p_value jsonb) returns jsonb as $ select jsonb_object_agg(t.key, t.value) from jsonb_each(p_input) as t(key, value) where value lt;gt; p_value; $ language sql immutable;
Тогда вы можете сделать:
update records set payload = remove_key_by_value(payload, to_jsonb(3)) where parent = 1;
Это предполагает, что payload
это определено как jsonb
(каким оно должно быть). Если это не так, вы должны бросить его: payload::jsonb
Комментарии:
1. Крошечная ошибка в элегантной функции, как вы, вероятно, заметили. Это фактически удаляет все, кроме ценности, как сейчас. Заменить предложение where на
where value != p_value;
Ответ №2:
Попробуй это
update records set payload = payload - 'x' where parent = 1 and payload-gt;gt;'x'::int = 3
Комментарии:
1.
x
может быть что угодно, я не могу написать запрос для всех возможных ключей. но спасибо, это может помочь кому-то другому