Saya memiliki dua tabel:
A [ID, column1, column2, column3]
B [ID, column1, column2, column3, column4]
A
akan selalu menjadi bagian dari B
(artinya semua kolom A
juga dalam B
).
Saya ingin memperbarui catatan dengan spesifik ID
dalam B
dengan datanya dari A
untuk semua kolom A
. Ini ID
ada di A
dan B
.
Apakah ada UPDATE
sintaks atau cara lain untuk melakukannya tanpa menentukan nama kolom, hanya mengatakan "setel semua kolom A" ?
Saya menggunakan PostgreSQL, jadi perintah non-standar tertentu juga diterima (namun, tidak disukai).
Jawaban:
Anda dapat menggunakan klausa FROM non-standar .
sumber
Pertanyaannya sudah lama tetapi saya merasa jawaban terbaik belum diberikan.
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. TetapiDO
pernyataan dengan kode PL / pgSQL yang menjalankan SQL dinamis benar-benar sintaks PostgreSQL non-standar.Mengasumsikan kolom yang cocok
b
untuk setiap kolom masuka
, 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.
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
ditentukanNOT NULL
(tetapi tidak harusB
),dan Anda tahu nama kolomnya
B
(tetapi tidak harusA
).The
NATURAL LEFT JOIN
bergabung berturut-turut darib
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 hilangA
, jadi hanya dapat diandalkan jika semua kolom diA
ditentukanNOT NULL
.Ada beberapa kemungkinan variasi, bergantung pada apa yang Anda ketahui tentang kedua tabel.
sumber
SET (column1) = (a.column)
) Postgres akan memperlakukannya sebagai jenis pembaruan lain dan memberi dan kesalahan seperti ini:source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
Saya telah bekerja dengan database IBM DB2 selama lebih dari satu dekade dan sekarang mencoba mempelajari PostgreSQL.
Ini berfungsi pada PostgreSQL 9.3.4, tetapi tidak berfungsi pada DB2 10.5:
Catatan: Masalah utama adalah DARI penyebab yang tidak didukung di DB2 dan juga tidak di ANSI SQL.
Ini berfungsi pada DB2 10.5, tetapi TIDAK berfungsi pada PostgreSQL 9.3.4:
AKHIRNYA! Ini berfungsi pada PostgreSQL 9.3.4 dan DB2 10.5:
sumber
B
, pernyataan pertama tidak melakukan apa - apa (baris asli tetap tidak tersentuh), sedangkan dua lainnya menimpa kolom dengan nilai NULL.Ini sangat membantu. Kode
bekerja dengan sempurna.
mencatat bahwa Anda memerlukan tanda kurung "" di
untuk membuatnya berhasil.
sumber
Belum tentu apa yang Anda tanyakan, tetapi mungkin menggunakan warisan postgres dapat membantu?
Ini menghindari kebutuhan untuk memperbarui B.
Tapi pastikan untuk membaca semua detailnya .
Jika tidak, apa yang Anda minta tidak dianggap sebagai praktik yang baik - hal-hal dinamis seperti pandangan dengan
SELECT * ...
tidak disarankan (karena sedikit kemudahan dapat merusak lebih banyak hal daripada hal bantuan), dan apa yang Anda minta akan setara denganUPDATE ... SET
perintah.sumber
Anda dapat membangun dan menjalankan sql dinamis untuk melakukan ini, tetapi sebenarnya ini tidak ideal
sumber
Coba Ikuti
DIEDIT: - Perbarui lebih dari satu kolom
sumber
UPDATE
di MySQL , tetapi tidak valid untuk PostgreSQL.