Питання старе, але я відчув, що найкращої відповіді ще не було.
Чи є UPDATE
синтаксис ... без вказівки назв стовпців ?
Загальне рішення з динамічним SQL
Вам не потрібно знати жодних назв стовпців, за винятком деяких унікальних стовпців, до яких можна приєднатися ( id
у прикладі). Надійно працює для будь-якого можливого кутового випадку, про який я думаю.
Це специфічно для PostgreSQL. Я будую динамічний код на основі інформаційної схеми , зокрема таблиці information_schema.columns
, яка визначена в стандарті SQL, і більшість основних RDBMS (крім 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 тут
Стара квадратна загадка.
Це стандартний SQL за винятком FROM
пункту .
Він працює незалежно від того , яка з колонок на насправді присутній в A
, але запит не може розрізняти між фактичними значеннями NULL і відсутніх стовпців в A
, так що це тільки надійним , якщо всі стовпці A
визначені NOT NULL
.
Існує кілька можливих варіантів, залежно від того, що ви знаєте про обидві таблиці.