MERGE¶
2番目のテーブルまたはサブクエリの値に基づいて、テーブルの値を挿入、更新、削除します。これは、2番目のテーブルが、ターゲットテーブルに新しい行(挿入)、変更された行(更新)、および/またはマークされた行(削除)を含む変更ログである場合に役立ちます。
このコマンドは、次のケースを処理するためのセマンティクスをサポートしています。
一致する値(更新および削除用)。
一致しない値(挿入用)
構文¶
条件:
パラメーター¶
target_tableマージするテーブルを指定します。
sourceターゲットテーブルと結合するテーブルまたはサブクエリを指定します。
join_exprターゲットテーブルとソースを結合する式を指定します。
matchedClause (更新または削除用)¶
WHEN MATCHED ... AND case_predicateオプションで、trueの場合に一致するケースを実行する式を指定します。
デフォルト: 値なし(一致するケースが常に実行されます)
WHEN MATCHED ... THEN { UPDATE { ALL BY NAME | SET ... } | DELETE }値が一致したときに実行するアクションを指定します。
ALL BY NAMEターゲットテーブルのすべての列をソースからの値で更新します。ターゲットテーブルの各列は、ソースの同名の列の値で更新されます。
ターゲットテーブルとソースは、同じ数の列を持ち、すべての列に同じ名前を付ける必要があります。ただし、列の順序はターゲットテーブルとソーステーブルで異なる場合があります。
SET col_name = expr [ , col_name = expr ... ]新しい列の値に対応する式を使用して、ターゲットテーブルの指定された列を更新します(ターゲットとソースの両方の関係を参照できます)
単一の
SET副次句では、更新する複数の列を指定できます。DELETEターゲットテーブルの行がソースと一致した場合に、その行を削除します。
notMatchedClause (挿入用)¶
WHEN NOT MATCHED ... AND case_predicateオプションで、trueの場合、一致しないケースが実行される式を指定します。
デフォルト: 値なし(一致しないケースが常に実行されます)
WHEN NOT MATCHED ... THEN INSERT.{ ALL BY NAME | [ ( col_name [ , ... ] ) ] VALUES ( expr [ , ... ] ) }値が一致しない場合に実行するアクションを指定します。
ALL BY NAMEターゲットテーブルのすべての列にソースからの値を挿入します。ターゲットテーブルの各列には、ソースから同名の列の値が挿入されます。
ターゲットテーブルとソースは、同じ数の列を持ち、すべての列に同じ名前を付ける必要があります。ただし、列の順序はターゲットテーブルとソーステーブルで異なる場合があります。
( col_name [ , ... ] )オプションで、ソースからの値を挿入するターゲットテーブルの1つ以上の列を指定します。
デフォルト: 値なし(ターゲットテーブルの列がすべて挿入されます)
VALUES ( expr [ , ... ] )挿入された列の値に対応する式を指定します(ソースリレーションを参照する必要があります)。
使用上の注意¶
単一の MERGE ステートメントには、複数の一致する句と一致しない句(つまり、
WHEN MATCHED ...とWHEN NOT MATCHED ...)を含めることができます。AND副次句を省略する一致または不一致の句(デフォルトの動作)は、ステートメント内のその句型の 最後 ` でなければなりません(例えば、 :code:`WHEN MATCHED ... 句の後にWHEN MATCHED AND ...句を続けることはできません)これを行うと、到達不能なケースが発生し、エラーが返されます。
結合動作を複製する¶
ソーステーブルの複数行がターゲットテーブルの1行と一致する場合、結果は決定論的または非決定論的となります。このセクションでは、これらのユースケースにおける MERGE の動作について説明します。
UPDATE と DELETE の非決定的結果¶
マージがソースの複数の行に対してターゲットテーブルの行を結合する場合、次の結合条件は非決定論的な結果を生成します(つまり、システムはターゲット行の更新または削除に使用するソース値を決定できません)
ターゲット行が選択され、複数の値で更新されます(例:
WHEN MATCHED ... THEN UPDATE)ターゲット行が選択され、更新と削除の両方が行われます(例:
WHEN MATCHED ... THEN UPDATE、WHEN MATCHED ... THEN DELETE)
この状況では、マージの結果は ERROR_ON_NONDETERMINISTIC_MERGE セッションパラメーターに指定された値に依存します。
TRUE (デフォルト値)の場合、マージはエラーを返します。
FALSE の場合、複製の中から1つの行が選択されて、更新または削除が実行されます。選択された行は定義されていません。
UPDATE と DELETE の決定的な結果¶
確定的マージは常にエラーなしで完了します。マージは、各ターゲット行に対して次の条件の*少なくとも1つ*を満たす場合、決定論的になります。
1つ以上のソース行が
WHEN MATCHED ... THEN DELETE句を満たし、その他のソース行がWHEN MATCHED句を満たさない正確に1つのソース行が
WHEN MATCHED ... THEN UPDATE句を満たし、および他のソース行はWHEN MATCHED句を満たさない。
これにより、 MERGE は UPDATE および DELETE コマンドと意味的に同等になります。
注釈
データソース(つまり、ソーステーブルまたはサブクエリ)の複数の行が ON 条件に基づいてターゲットテーブルと一致する場合のエラーを回避するには、ソース句で GROUP BY を使用して、各ターゲット行がソース内の(最大)1つの行に対して結合されるようにします。
次の例では、 src に同じ k 値を持つ複数の行が含まれると仮定します。ターゲット行の行を同じ値 v で更新するためにどの値(k)が使用されるかはあいまいです。MAX 関数および GROUP BY を使用することにより、クエリは src の v のどの値が使用されているかを明確に示します。
INSERT の決定的な結果¶
確定的マージは常にエラーなしで完了します。
MERGE ステートメントに WHEN NOT MATCHED ... THEN INSERT 句が含まれ、ターゲットに一致する行がない場合、およびソースに重複する値が含まれる場合、ターゲットはソース内の*各*コピーに対して行のコピーを1つ取得します。例については、 重複ソースとマージを実行する をご参照ください。
例¶
以下の例では、 MERGE コマンドを使用しています。
値を更新する基本的なマージを実行する¶
以下の例では、ソーステーブルの値を使用してターゲットテーブルの値を更新する基本的なマージを実行します。2つのテーブルを作成し、ロードします。
テーブルの値を表示します。
MERGE ステートメントを実行します。
ターゲットテーブルに新しい値を表示します(ソーステーブルは変更されません)
複数の操作による基本的なマージを実行する¶
複数のオペレーション(INSERT 、 UPDATE 、 DELETE)を組み合わせた基本的なマージを行います。
2つのテーブルを作成し、ロードします。
テーブルの値を表示します。
以下のマージ例は、 merge_example_mult_target テーブルに対して以下のアクションを実行します。
merge_example_mult_sourceで同じidを持つ行のmarked列がYになっているため、idが1に設定された行を削除します。merge_example_mult_source内の同じ行のisnewstatusが1に設定されているためidが2に設定されている行のval値とstatus値を、merge_example_mult_source内の同じidを持つ行の値で更新します。idが3に設定された行のval値を、merge_example_mult_source内の同じidを持つ行の値で更新します。merge_example_mult_source内のこの行では、isnewstatusが0に設定されているため、 MERGE ステートメントはmerge_example_mult_targetのstatus値を更新しません。merge_example_mult_sourceに行が存在し、merge_example_mult_targetに一致する行がないため、idを4に設定して行を挿入します。
マージ結果を見るには、 merge_example_mult_target テーブルの値を表示します。
ALL BY NAME を使用してマージを実行します¶
次の例は、ソーステーブルの値を使用してターゲットテーブルの値を挿入および更新するマージを実行します。この例では、 WHEN MATCHED ... THEN ALL BY NAME および WHEN NOT MATCHED ... THEN ALL BY NAME サブ句を使用して、マージがすべての列に適用されることを指定しています。
列の数と列名が同じで、2つの列の順序が異なる2つのテーブルを作成します。
テーブルをロードします。
テーブルの値を表示します。
MERGE ステートメントを実行します。
ターゲットテーブルに新しい値を表示します。
重複ソースとマージを実行する¶
ソースに重複する値があり、ターゲットに一致する値がないマージを実行します。ソース記録のすべてのコピーがターゲットに挿入されます。詳細については、 INSERT の決定的な結果 を参照してください。
両方のテーブルを切り捨て、重複を含む新しい行をソーステーブルにロードします。
merge_example_target には値がありません。merge_example_source テーブルの値を表示します。
MERGE ステートメントを実行します。
ターゲットテーブルに新しい値を表示します。
決定論的結果と非決定論的結果とのマージを実行する¶
非決定的および決定的結果を生成する結合を使用して記録をマージします。
2つのテーブルを作成し、ロードします。
次の例でマージを実行すると、複数の更新が互いに競合します。ERROR_ON_NONDETERMINISTIC_MERGE セッションパラメーターが true に設定されている場合、 MERGE ステートメントはエラーを返します。そうでない場合、 MERGE ステートメントは、重複行(定義されていない行)のいずれかの値(例えば、 11 、 12 、 13)で merge_example_target_clone.v を更新します。
更新と削除は互いに競合します。ERROR_ON_NONDETERMINISTIC_MERGE セッションパラメーターが true に設定されている場合、 MERGE ステートメントはエラーを返します。そうでない場合、 MERGE ステートメントは、行を削除するか、重複行(定義されていない行)のいずれかの値(例えば、 12 や 13)で merge_example_target_clone.v を更新します。
複数の削除が競合することはありません。どの句にも一致しない結合値は、削除を妨げません(merge_example_src.v = 13)MERGE ステートメントは成功し、対象行は削除されます。
どの句にも一致しない結合値は、更新を妨げません(merge_example_src.v = 12, 13)MERGE ステートメントは成功し、ターゲット行は target.v = 11 に設定されます。
各ターゲット行がソース内の1つの行に対して結合されるように、ソース句で GROUP BY を使用します。
DATE の値に基づいてマージを実行する¶
次の例では、 members テーブルに、地元のジムに支払われた名前、住所、および現在の料金(members.fee)が格納されています。signup テーブルには、各メンバーの登録日(signup.date)が保存されます。MERGE ステートメントは、無料トライアルの期限が切れた後、30日以上前にジムに参加したメンバーに標準の$40料金を適用します。