Предполагая, что (p_id, a_id)
является PK - или, по крайней мере, UNIQUE
и NOT NULL
, это один из способов:
UPDATE products AS u
SET best = COALESCE(u2.best, 0)
FROM products AS p
LEFT JOIN ( VALUES
(111, 84, 1),
(222, 84, 2)
) AS u2(p_id, a_id, best) USING (p_id, a_id)
WHERE u.a_id = 84
AND u.a_id = p.p_id
AND u.p_id = p.p_id
RETURNING u2.p_id, u2.a_id, u2.best;
Сложность в том, что список FROM
для UPDATE
является эквивалентом INNER JOIN
, тогда как вам нужен OUTER JOIN
. Этот обходной путь добавляет таблицу products
в список FROM
(который обычно является избыточным), чтобы действовать в качестве левой таблицы для LEFT OUTER JOIN
. Тогда работает INNER JOIN
с products
до products
.
Чтобы дополнительно ограничить a_id = 84
, добавьте еще одно предложение WHERE
, сказав так. Это делает a_id = 84
избыточным в выражении VALUES
, но оставляйте его там, чтобы избежать множественных объединений, которые будут отфильтрованы позже. Дешевле.
Если у вас нет PK или каких-либо других (комбинаций) UNIQUE NOT NULL
столбцов, вы можете вернуться к системному столбцу ctid
для объединения products
строк. Пример: