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