Ответ 1
Ваш UPDATE
запрос должен выглядеть следующим образом:
UPDATE table2 t2
SET val2 = t1.val1
FROM table1 t1
WHERE t2.table2_id = t1.table2_id
AND t2.val2 IS DISTINCT FROM t1.val1; -- optional, see below
Как и было, между отдельными строками двух таблиц не было связи. Каждая строка будет извлечена из table1
для каждой строки в table2
. Это не имело смысла (дорогостоящим способом) и также вызывало синтаксическую ошибку, потому что выражению подзапроса в этом месте разрешено возвращать только одно значение.
Я исправил это, соединив две таблицы на table2_id
. Замените это тем, что на самом деле связывает два.
Я переписал UPDATE
, чтобы присоединиться к table1
(с предложением FROM
) вместо того, чтобы запускать коррелированные подзапросы, потому что это обычно быстрее на порядок.
Это также предотвращает аннулирование table2.val2
, если в table1
не найдено подходящей строки. Вместо этого с такими формами запроса ничего не происходит.
Вы можете добавить табличные выражения в список FROM
, как если бы они были обычным SELECT
(таблицы, подзапросы, функции, возвращающие множество,...). Руководство:
from_list
Список табличных выражений, позволяющий столбцам из других таблиц появляются в условии
WHERE
и выражениях обновления. Это аналогично списку таблиц, которые можно указать в предложенииFROM
SELECT
заявления. Обратите внимание, что таблица назначения не должна появляться вfrom_list
, если только вы не собираетесь самостоятельно присоединиться (в этом случае появляются с псевдонимом вfrom_list
).
В последнем предложении WHERE
запрещены обновления, которые ничего не изменят - что практически всегда является хорошей идеей (почти полная стоимость, но без выгоды, применяются экзотические исключения). Если и старое, и новое значение гарантированно равны NOT NULL
, упростите до:
AND t2.val2 <> t1.val1