サーチ…


前書き

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