質問は古いですが、最良の答えはまだ得られていないと感じました。
列名を指定せずにUPDATE
構文... はありますか?
動的SQLを使用した一般的なソリューション
結合する一意の列(id
例)を除いて、列名を知る必要はありません。考えられるあらゆるコーナーケースで確実に機能します。
これはPostgreSQLに固有です。information_schemaに基づいて動的コードを構築しています。特にinformation_schema.columns
、SQL標準で定義されているtable であり、ほとんどの主要なRDBMS(Oracleを除く)がそれを持っています。しかし、動的SQLを実行するPL / pgSQLコードDO
を含むステートメントは、完全に非標準の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。
この構文は、質問されるずっと前に、2006年にPostgres 8.2で導入されました。 マニュアルの詳細。
関連:
の列のリスト 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
Old sqlfiddle。
これは、FROM
句を除いて標準SQL です。
どの列が実際に存在してA
いても機能しますが、クエリは実際のNULL値と欠落している列を区別できないためA
、すべての列A
が定義されている場合にのみ信頼できますNOT NULL
。
両方のテーブルについての知識に応じて、複数の可能なバリエーションがあります。