Удалить атрибут по его ключу из массива jsonb в цикле - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь удалить атрибут по его ключу из массива jsonb в цикле

groups = '
[
    {"id": "1", "name": "Ann", "age": 20 },
    {"id": "2", "name": "Margaret", "age": 30 }
]';

FOR i IN 0..(jsonb_array_length(groups) - 1)
LOOP
groups = groups - '{age}';
END LOOP;

/* but nothing happened, I see [{"id": "1", "age": 20, "name": "Ann"}, {"id": "2", "age": 30, "name": "Margaret"}] */

RAISE NOTICE '%', groups;

, но ничего не произошло.Как я могу это сделать?

1 Ответ

0 голосов
/ 15 января 2019

Вы можете изменять только один элемент массива на каждом шаге цикла, поэтому для агрегирования результатов необходимо использовать новую переменную:

do $$
declare 
    groups jsonb = 
    '[
        {"id": "1", "name": "Ann", "age": 20 },
        {"id": "2", "name": "Margaret", "age": 30 }
    ]';
    new_groups jsonb = '[]';
begin
    for i in 0..jsonb_array_length(groups) - 1
    loop
        new_groups:= new_groups || (groups->i) - 'age';
    end loop;
    raise notice '%', new_groups;
end $$;

NOTICE:  [{"id": "1", "name": "Ann"}, {"id": "2", "name": "Margaret"}]
DO

Лучше сделать то же самое в одном запросе без цикла и дополнительной переменной:

do $$
declare 
    groups jsonb = 
    '[
        {"id": "1", "name": "Ann", "age": 20 },
        {"id": "2", "name": "Margaret", "age": 30 }
    ]';
begin
    select jsonb_agg(value- 'age')
    from jsonb_array_elements(groups)
    into groups;
    raise notice '%', groups;
end $$;
...