サーチ…
前書き
MERGE(「更新または挿入」のためにUPSERTと呼ばれることも多い)では、新しい行を挿入するか、行がすでに存在する場合は既存の行を更新することができます。重要な点は、操作全体を原子的に実行して(データの一貫性を保つため)、クライアント/サーバー・システム内の複数のSQL文に対する通信オーバーヘッドを防ぐことです。
ターゲットマッチソースを作るためのマージ
MERGE INTO targetTable t
USING sourceTable s
ON t.PKID = s.PKID
WHEN MATCHED AND NOT EXISTS (
SELECT s.ColumnA, s.ColumnB, s.ColumnC
INTERSECT
SELECT t.ColumnA, t.ColumnB, s.ColumnC
)
THEN UPDATE SET
t.ColumnA = s.ColumnA
,t.ColumnB = s.ColumnB
,t.ColumnC = s.ColumnC
WHEN NOT MATCHED BY TARGET
THEN INSERT (PKID, ColumnA, ColumnB, ColumnC)
VALUES (s.PKID, s.ColumnA, s.ColumnB, s.ColumnC)
WHEN NOT MATCHED BY SOURCE
THEN DELETE
;
注: AND NOT EXISTS
部分は、変更されていないレコードの更新を防止します。 INTERSECT
構造体を使用すると、特別な処理を行わずにNULL値の列を比較することができます。
MySQL:ユーザーを名前で数える
同じ名前のユーザー数を知りたいとします。次のようにテーブルusers
を作成しましょう。
create table users(
id int primary key auto_increment,
name varchar(8),
count int,
unique key name(name)
);
さて、ジョーという名前の新しいユーザーを見つけたので、彼を考慮に入れたいと思います。これを達成するには、名前を持つ既存の行があるかどうかを判断する必要があります。存在する場合は増分カウントに更新します。一方、既存の行がない場合は、作成する必要があります。
MySQLは次の構文を使用します: insert ... on duplicate key update ...この場合:
insert into users(name, count)
values ('Joe', 1)
on duplicate key update count=count+1;
PostgreSQL:ユーザーを名前で数える
同じ名前のユーザー数を知りたいとします。次のようにテーブルusers
を作成しましょう。
create table users(
id serial,
name varchar(8) unique,
count int
);
さて、ジョーという名前の新しいユーザーを見つけたので、彼を考慮に入れたいと思います。これを達成するには、名前を持つ既存の行があるかどうかを判断する必要があります。存在する場合は増分カウントに更新します。一方、既存の行がない場合は、作成する必要があります。
PostgreSQLは次の構文を使用します: insert ... on conflict ... do update ...。この場合:
insert into users(name, count)
values('Joe', 1)
on conflict (name) do update set count = users.count + 1;
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow