Запрос на обновление столбца jsonb вставляет только первое значение - PullRequest
0 голосов
/ 09 мая 2018

Почему, если вы используете jsonb_set в качестве новых значений в запросе UPDATE, он обновляет только первую строку набора результатов?

Смотрите этот пример здесь: http://sqlfiddle.com/#!17/0bdd8/5

Есть две записи в реакциях на одно и то же сообщение, но когда я пытаюсь назначить случайное значение, привязанное к имени пользователя, оно вставляет его только для первого значения, а не для второго:

UPDATE posts
SET    a_to_b = jsonb_set(posts.a_to_b, array[username::text], to_jsonb(random()))
FROM   reactions 
WHERE  posts.id = reactions.post_id;

1 Ответ

0 голосов
/ 09 мая 2018

В предложении FROM имеется более одной строки для одной изменяемой строки. Документация объясняет это ясно:

При использовании FROM вы должны убедиться, что соединение создает не более одной выходной строки для каждой строки, подлежащей изменению. Другими словами, целевая строка не должна соединяться с более чем одной строкой из других таблиц. Если это так, то только одна из строк соединения будет использоваться для обновления целевой строки, но какая из них будет использоваться, трудно предсказать.


Вы можете выполнить одно обновление, сгруппировав ожидаемое значение в подзапросе. Используйте агрегатную функцию jsonb_object_agg():

update posts p
set a_to_b = agg
from (
    select p.id, jsonb_object_agg(username, random()) as agg
    from posts p
    join reactions r on p.id = r.post_id
    group by p.id
) s
where s.id = p.id;

SqlFiddle.

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

do $$
declare rec record;
begin
    for rec in
        select * 
        from posts p
        join reactions r on p.id = r.post_id
    loop
        update posts
        set a_to_b = jsonb_set(a_to_b, array[rec.username], to_jsonb(random()))
        where posts.id = rec.post_id;
    end loop;
end $$;

Второе решение может оказаться неоптимальным, особенно для большого количества агрегированных значений.

...