Soru eski ama en iyi cevabın henüz verilmediğini hissettim.
Bir ... var mı UPDATE
Sütun adlarını belirtmeden ... sözdizimi ?
Dinamik SQL ile genel çözüm
Katılmak için bazı benzersiz sütunlar dışında herhangi bir sütun adı bilmenize gerek yoktur (id
örnekte). Aklıma gelen herhangi bir olası köşe durumunda güvenilir bir şekilde çalışıyor.
Bu, PostgreSQL'e özgüdür. Bilgi şemasına information_schema.columns
, özellikle SQL standardında tanımlanan ve en büyük RDBMS'de (Oracle hariç) buna sahip olan tabloya dayalı dinamik kod oluşturuyorum . Ancak dinamik SQL çalıştıran PL / pgSQL kodlu bir DO
ifade , tamamen standart olmayan PostgreSQL sözdizimidir.
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$;
Her sütun b
için eşleşen bir sütun varsayarsak , ancak tersi olmaz. ek sütunlar olabilir.a
b
WHERE b.id = 123
seçili bir satırı güncellemek için isteğe bağlıdır.
SQL Fiddle.
Daha fazla açıklamayla ilgili yanıtlar:
Düz SQL ile kısmi çözümler
Paylaşılan sütunların listesiyle
Yine de her iki tablonun paylaştığı sütun adlarının listesini bilmeniz gerekir. Birden çok sütunu güncellemek için bir sözdizimi kısayolu ile - her durumda şimdiye kadar önerilen diğer yanıtlardan daha kısadır.
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.
Bu sözdizimi, soru sorulmadan çok önce, 2006 yılında Postgres 8.2 ile tanıtıldı. Kılavuzdaki ayrıntılar.
İlişkili:
İçindeki sütunların listesi ile B
Eğer tüm sütunlar A
tanımlanmıştır NOT NULL
(şart olmamakla birlikte B
),
ve sen biliyorsun sütun isimlerini B
(şart olmamakla birlikte 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
Bir satırı katılır b
aynı adı taşıyan tüm sütunlar aynı değerleri barındırdığı yerde. Bu durumda bir güncellemeye ihtiyacımız yoktur (hiçbir şey değişmez) ve bu satırları sürecin başlarında ortadan kaldırabiliriz ( WHERE b.id IS NULL
).
Hala eşleşen bir satır bulmamız gerekiyor.b.id = ab.id
Dış sorguda .
db <> fiddle here
Eski sqlfiddle.
Bu, yan tümce hariçFROM
standart SQL'dir .
Hangi sütunlarda gerçekten mevcut olursa olsun çalışır A
, ancak sorgu gerçek NULL değerleri ile eksik sütunları birbirinden ayırt edemez A
, bu nedenle yalnızca içindeki tüm sütunlarA
tanımlanmışsaNOT NULL
.
Her iki tablo hakkında bildiklerinize bağlı olarak birden fazla olası varyasyon vardır .