#sql #arrays #json #postgresql #postgresql-9.5
#sql #массивы #json #postgresql #postgresql-9.5
Вопрос:
Я пытаюсь обновить имя ключа 1 поля в моем jsonb
списке.
Исходные данные
select jsonb_array_elements(status_history) from deals;
>>> [{"date": "2020-10-02T12:05:02.728691", "state": "gathering_info"}, {"date": "2020-10-08T10:15:20.798500", "state": "archived"}, {"date": "2020-10-08T10:43:17.651033", "state": "gathering_info"}]
>>> ...
Я могу получить каждый элемент с помощью этой функции
select jsonb_array_elements(status_history) from deals;
>>> {"date": "2020-10-02T11:51:55.624263", "state": "gathering_info"}
Я хочу обновить state
ключ, чтобы он был status
, и я пытаюсь это сделать
update deals set elem=elem amp; {'status': elem->'state'} from (select jsonb_array_elements(status_history) from deals) elem;
update deals set elem->'status' = elem->'state' from (select jsonb_array_elements(status_history) from deals) elem;
Но это не работает. Как я могу это сделать?
Ответ №1:
Вы можете отменить проверку массива, отслеживая положение каждого объекта, изменить имя ключа в каждом отдельном элементе с помощью операторов -
, а ||
затем повторно сгруппировать. Предполагая, что первичный ключ вашей таблицы id
, вы могли бы сформулировать это как:
update deals d
set status_history = d1.status_history
from (
select d.id,
json_agg(
x.obj - 'state' || jsonb_build_object('status', x.obj -> 'state')
order by x.n
) as status_history
)
from deals d
cross join lateral jsonb_array_elements(d.status_history) with ordinality as x(obj, n)
group by d.id
) d1
where d1.id = d.id