Pertanyaannya sudah lama tetapi saya merasa jawaban terbaik belum diberikan.
Apakah ada UPDATE
sintaks ... tanpa menentukan nama kolom ?
Solusi umum dengan SQL dinamis
Anda tidak perlu mengetahui nama kolom apa pun kecuali beberapa kolom unik untuk digabungkan ( id
dalam contoh). Bekerja dengan andal untuk setiap kemungkinan kasus sudut yang dapat saya pikirkan.
Ini khusus untuk PostgreSQL. Saya membangun kode dinamis berdasarkan information_schema , khususnya tabel information_schema.columns
, yang didefinisikan dalam standar SQL dan sebagian besar RDBMS (kecuali Oracle) memilikinya. Tetapi DO
pernyataan dengan kode PL / pgSQL yang menjalankan SQL dinamis benar-benar sintaks PostgreSQL non-standar.
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$;
Mengasumsikan kolom yang cocok b
untuk setiap kolom masuk a
, tetapi tidak sebaliknya. b
dapat memiliki kolom tambahan.
WHERE b.id = 123
bersifat opsional, untuk memperbarui baris yang dipilih.
SQL Fiddle.
Jawaban terkait dengan penjelasan lebih lanjut:
Solusi parsial dengan SQL biasa
Dengan daftar kolom bersama
Anda tetap perlu mengetahui daftar nama kolom yang dimiliki kedua tabel tersebut. Dengan pintasan sintaks untuk memperbarui beberapa kolom - lebih pendek dari jawaban lain yang disarankan sejauh ini.
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.
Sintaks ini diperkenalkan dengan Postgres 8.2 pada tahun 2006, jauh sebelum pertanyaan diajukan. Detail di manual.
Terkait:
Dengan daftar kolom dalam B
Jika semua kolom A
ditentukan NOT NULL
(tetapi tidak harus B
),
dan Anda tahu nama kolomnya B
(tetapi tidak harus 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;
The NATURAL LEFT JOIN
bergabung berturut-turut dari b
mana semua kolom dengan nama yang sama memegang nilai-nilai yang sama. Kami tidak memerlukan pembaruan dalam kasus ini (tidak ada yang berubah) dan dapat menghilangkan baris tersebut di awal proses ( WHERE b.id IS NULL
).
Kami masih perlu menemukan baris yang cocok, jadi b.id = ab.id
di kueri luar.
db <> biola di sini Sqlfiddle
tua .
Ini adalah SQL standar kecuali untuk FROM
klausa .
Ini berfungsi tidak peduli di kolom mana sebenarnya ada A
, tetapi kueri tidak dapat membedakan antara nilai NULL aktual dan kolom yang hilang A
, jadi hanya dapat diandalkan jika semua kolom di A
ditentukan NOT NULL
.
Ada beberapa kemungkinan variasi, bergantung pada apa yang Anda ketahui tentang kedua tabel.