Несколько ОБНОВЛЕНИЕ ... ОТ одного ряда не работает - PullRequest
2 голосов
/ 13 октября 2019

Я пытаюсь сделать несколько обновлений, но это работает только для первой строки.

У меня есть таблица "пользователи" с 2 записями:

create table users
(
  uid        serial                                 not null
    constraint users_pkey
      primary key,
  balance    numeric                  default 0     not null
);


INSERT INTO public.users (uid, balance) VALUES (2, 100);
INSERT INTO public.users (uid, balance) VALUES (1, 100);

Я пытаюсь ОБНОВИТЬПользователь "1" дважды с запросом, но он обновляется только один раз: баланс для пользователя "1" становится "105", а не "115"

update users as u
set balance = balance + c.bal
from (values (1, 5),
             (1, 10)
     ) as c(uid, bal)
where c.uid = u.uid;

Почему он не обновляется для всех строк из подзапроса?

Ответы [ 2 ]

1 голос
/ 13 октября 2019

Документация postgresql не дает оснований для такого поведения, но указывает его.

Соответствующая цитата

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

Использование SELECT с GROUP BYобъединить строки перед выполнением обновления.

0 голосов
/ 13 октября 2019

Перед объединением необходимо выполнить агрегирование во внутреннем запросе:

update users as u
set balance = balance + d.bal
from ( 
  select uid, sum(bal) bal
  from ( values (1, 5), (1, 10) ) as c(uid, bal)
  group by uid
) d
where d.uid = u.uid;

Демонстрация на БД Fiddle :

| uid | balance |
| --- | ------- |
| 2   | 100     |
| 1   | 115     |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...