Вопрос старый, но я чувствовал, что лучшего ответа пока нет.
Есть ли UPDATEсинтаксис ... без указания имен столбцов ?
Общее решение с динамическим SQL
Вам не нужно знать какие-либо имена столбцов, кроме некоторых уникальных столбцов, к которым нужно присоединиться ( idв примере). Работает надежно для любого возможного углового случая, о котором я могу подумать.
Это характерно для PostgreSQL. Я создаю динамический код на основе information_schema , в частности таблицы information_schema.columns, которая определена в стандарте SQL, и большинство основных СУБД (кроме Oracle) имеют ее. Но DOоператор с кодом PL / pgSQL, выполняющий динамический SQL, является совершенно нестандартным синтаксисом PostgreSQL.
DO
$do$
BEGIN
EXECUTE (
SELECT
'UPDATE b
SET (' || string_agg( quote_ident(column_name), ',') || ')
= (' || string_agg('a.' || quote_ident(column_name), ',') || ')
FROM a
WHERE b.id = 123
AND a.id = b.id'
FROM information_schema.columns
WHERE table_name = 'a' -- table name, case sensitive
AND table_schema = 'public' -- schema name, case sensitive
AND column_name <> 'id' -- all columns except id
);
END
$do$;
Предполагая, что соответствующий столбец входит bдля каждого столбца в a, но не наоборот. bмогут иметь дополнительные столбцы.
WHERE b.id = 123 не является обязательным, чтобы обновить выбранную строку.
SQL Fiddle.
Связанные ответы с дополнительными пояснениями:
Частичные решения с простым SQL
Со списком общих столбцов
Вам все еще нужно знать список имен столбцов, которые используются в обеих таблицах. С ярлыком синтаксиса для обновления нескольких столбцов - в любом случае короче, чем предлагали другие ответы.
UPDATE b
SET ( column1, column2, column3)
= (a.column1, a.column2, a.column3)
FROM a
WHERE b.id = 123 -- optional, to update only selected row
AND a.id = b.id;
SQL Fiddle.
Этот синтаксис был представлен в Postgres 8.2 в 2006 году, задолго до того, как был задан вопрос. Подробности в инструкции.
Связанный:
Со списком столбцов в B
Если все столбцы Aопределены NOT NULL(но не обязательно B),
и вы знаете имена столбцов B(но не обязательно A).
UPDATE b
SET (column1, column2, column3, column4)
= (COALESCE(ab.column1, b.column1)
, COALESCE(ab.column2, b.column2)
, COALESCE(ab.column3, b.column3)
, COALESCE(ab.column4, b.column4)
)
FROM (
SELECT *
FROM a
NATURAL LEFT JOIN b -- append missing columns
WHERE b.id IS NULL -- only if anything actually changes
AND a.id = 123 -- optional, to update only selected row
) ab
WHERE b.id = ab.id;
Присоединяется NATURAL LEFT JOINк строке, в bкоторой все столбцы с одинаковым именем содержат одинаковые значения. В этом случае нам не нужно обновление (ничего не меняется), и мы можем удалить эти строки на ранней стадии процесса ( WHERE b.id IS NULL).
Нам все еще нужно найти соответствующую строку, поэтому b.id = ab.idво внешнем запросе.
db <> fiddle here
Старый sqlfiddle.
Это стандартный SQL, за исключением FROMпредложения .
Он работает независимо от того, какие столбцы на самом деле присутствуют A, но запрос не может различить фактические значения NULL и отсутствующие столбцы A, поэтому он является надежным только в том случае, если все столбцы Aопределены NOT NULL.
Есть несколько возможных вариантов, в зависимости от того, что вы знаете об обеих таблицах.