MERGE - Amazon Redshift

MERGE

ソーステーブルの行を条件付きでターゲットテーブルにマージします。従来、これは複数の insert、update、delete ステートメントを別々に使用することによってのみ実現していました。MERGE で組み合わせることができる操作の詳細については、「UPDATE」、「DELETE」、「INSERT」を参照してください。

構文

MERGE INTO target_table USING source_table [ [ AS ] alias ] ON match_condition [ WHEN MATCHED THEN { UPDATE SET col_name = { expr } [,...] | DELETE } WHEN NOT MATCHED THEN INSERT [ ( col_name [,...] ) ] VALUES ( { expr } [, ...] ) | REMOVE DUPLICATES ]

パラメータ

target_table

MERGE ステートメントがマージされる一時または永続テーブル。

source_table

target_table にマージする行を提供する一時または永続テーブル。source_table は、Spectrum テーブルにすることもできます。

alias

source_table の一時的な代替名。

このパラメータはオプションです。alias の先頭に AS を付けることもできます。

match_condition

ソーステーブルの列とターゲットテーブルの列の間に等しい述語を指定します。これを使用して、source_table の行が target_table の行と一致するかどうかを判断します。条件が満たされると、MERGE はその行に対して matched_clause を実行します。それ以外の場合は、MERGE はその行に対して not_matched_clause を実行します。

WHEN MATCHED

ソース行とターゲット行の一致条件が True と評価された場合に実行するアクションを指定します。UPDATE アクションまたは DELETE アクションのいずれかを指定できます。

UPDATE

target_table 内の一致した行を更新します。指定した col_name の値のみが更新されます。

DELETE

target_table 内の一致した行を削除します。

WHEN NOT MATCHED

一致条件が False または Unknown と評価された場合に実行するアクションを指定します。この句には INSERT 挿入アクションのみを指定できます。

INSERT

match_condition に従って、target_table のどの行とも一致しない source_table の target_table 行に挿入します。ターゲットの col_name は、任意の順序でリストできます。col_name の値を指定しない場合、デフォルトの順序は、テーブルのすべての列が宣言した順序になります。

col_name

修正する 1 つまたは複数の列名。ターゲット列を指定する際にテーブル名を含めないでください。

expr

col_name の新しい値を定義する式。

REMOVE DUPLICATES

MERGE コマンドを簡易モードで実行することを指定します。簡易モードには次の要件があります。

  • target_tablesource_table は、列数が同じで、列タイプも互換性がある必要があります。

  • MERGE コマンドから WHEN 句、UPDATE 句、INSERT 句を省略します。

  • MERGE コマンドで REMOVE DUPLICATES 句を使用します。

簡易モードの場合、MERGE は次の操作を行います。

  • source_table と一致する target_table 内の行は、source_table の値と一致するように更新されます。

  • target_table と一致しない source_table 内の行は、target_table に挿入されます。

  • target_table 内の複数の行が source_table 内の同じ行と一致する場合、重複する行は削除されます。Amazon Redshift は 1 つの行を保持し、それを更新します。source_table 内の行と一致しない重複行は変更されません。

REMOVE DUPLICATES を使用すると、WHEN MATCHED や WHEN NOT MATCHED を使用するよりもパフォーマンスが向上します。target_tablesource_table に互換性があり、target_table に重複業を保持する必要がない場合は、REMOVE DUPLICATES を使用することをお勧めします。

使用に関する注意事項

  • MERGE ステートメントを実行するには、source_tabletarget_table の両方の所有者であるか、それらのテーブルの SELECT 権限を持っている必要があります。さらに、MERGE ステートメントに含まれるオペレーションに応じて、target_table の UPDATE、DELETE、および INSERT 権限が必要です。

  • target_table をシステムテーブル、カタログテーブル、または外部テーブルにすることはできません。

  • source_tabletarget_table を同じテーブルにすることはできません。

  • MERGE ステートメントで WITH 句を使用することはできません。

  • target_table 内の行を source_table 内の複数の行と一致させることはできません。

    次の例を考えます。

    CREATE TABLE target (id INT, name CHAR(10)); CREATE TABLE source (id INT, name CHAR(10)); INSERT INTO target VALUES (1, 'Bob'), (2, 'John'); INSERT INTO source VALUES (1, 'Tony'), (1, 'Alice'), (3, 'Bill'); MERGE INTO target USING source ON target.id = source.id WHEN MATCHED THEN UPDATE SET id = source.id, name = source.name WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name); ERROR: Found multiple matches to update the same tuple. MERGE INTO target USING source ON target.id = source.id WHEN MATCHED THEN DELETE WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name); ERROR: Found multiple matches to update the same tuple.

    ID 値が 1source テーブルに複数の行があるため、どちらの MERGE ステートメントでも操作は失敗します。

  • match_conditionexpr はSUPER 型の列を部分的に参照することはできません。例えば、SUPER 型のオブジェクトが配列または構造体である場合、その列の個々の要素を match_conditionexpr に使用することはできませんが、列全体を使用することはできます。

    次の例を考えます。

    CREATE TABLE IF NOT EXISTS target (key INT, value SUPER); CREATE TABLE IF NOT EXISTS source (key INT, value SUPER); INSERT INTO target VALUES (1, JSON_PARSE('{"key": 88}')); INSERT INTO source VALUES (1, ARRAY(1, 'John')), (2, ARRAY(2, 'Bill')); MERGE INTO target USING source ON target.key = source.key WHEN matched THEN UPDATE SET value = source.value[0] WHEN NOT matched THEN INSERT VALUES (source.key, source.value[0]); ERROR: Partial reference of SUPER column is not supported in MERGE statement.

    SUPER 型の詳細については、「SUPER 型」を参照してください。

  • source_table が大きい場合は、target_tablesource_table の両方の結合列を分散キーとして定義するとパフォーマンスが向上する可能性があります。

  • REMOVE DUPLICATES 句を使用するには、target_table に対する SELECT、INSERT、および DELETE アクセス許可が必要です。

  • source_table はビューまたはサブクエリです。次に、source_table が重複する行を削除するサブクエリである MERGE ステートメントの例を示します。

    MERGE INTO target USING (SELECT id, name FROM source GROUP BY 1, 2) as my_source ON target.id = my_source.id WHEN MATCHED THEN UPDATE SET id = my_source.id, name = my_source.name WHEN NOT MATCHED THEN INSERT VALUES (my_source.id, my_source.name);

次の例では、2 つのテーブルを作成し、それらに対して MERGE オペレーションを実行して、ターゲットテーブルの一致する行を更新し、一致しない行を挿入します。次に、ソーステーブルに別の値を挿入し、別の MERGE オペレーションを実行します。今度は、一致する行を削除して、ソーステーブルから新しい行を挿入します。

まず、ソーステーブルとターゲットテーブルを作成してデータを入力します。

CREATE TABLE target (id INT, name CHAR(10)); CREATE TABLE source (id INT, name CHAR(10)); INSERT INTO target VALUES (101, 'Bob'), (102, 'John'), (103, 'Susan'); INSERT INTO source VALUES (102, 'Tony'), (103, 'Alice'), (104, 'Bill'); SELECT * FROM target; id | name -----+------------ 101 | Bob 102 | John 103 | Susan (3 rows) SELECT * FROM source; id | name -----+------------ 102 | Tony 103 | Alice 104 | Bill (3 rows)

次に、ソーステーブルをターゲットテーブルにマージし、ターゲットテーブルを一致する行で更新し、一致しない行をソーステーブルから挿入します。

MERGE INTO target USING source ON target.id = source.id WHEN MATCHED THEN UPDATE SET id = source.id, name = source.name WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name); SELECT * FROM target; id | name -----+------------ 101 | Bob 102 | Tony 103 | Alice 104 | Bill (4 rows)

なお、ID 値が 102 と 103 の行は、ターゲットテーブルの名前値と一致するように更新されます。また、ID 値が 104 で名前値が Bill の新しい行がターゲットテーブルに挿入されます。

次に、ソーステーブルに新しい行を挿入します。

INSERT INTO source VALUES (105, 'David'); SELECT * FROM source; id | name -----+------------ 102 | Tony 103 | Alice 104 | Bill 105 | David (4 rows)

最後に、MERGE オペレーションを実行して、ターゲットテーブルから一致する行を削除し、一致しない行を挿入します。

MERGE INTO target USING source ON target.id = source.id WHEN MATCHED THEN DELETE WHEN NOT MATCHED THEN INSERT VALUES (source.id, source.name); SELECT * FROM target; id | name -----+------------ 101 | Bob 105 | David (2 rows)

ID 値が 102、103、104 の行がターゲットテーブルから削除され、ID 値が 105 で名前値が David の新しい行がターゲットテーブルに挿入されます。

次の例は、REMOVE DUPLICATES 句を使用した MERGE コマンドの簡略化された構文を示しています。

CREATE TABLE target (id INT, name CHAR(10)); CREATE TABLE source (id INT, name CHAR(10)); INSERT INTO target VALUES (30, 'Tony'), (11, 'Alice'), (23, 'Bill'); INSERT INTO source VALUES (23, 'David'), (22, 'Clarence'); MERGE INTO target USING source ON target.id = source.id REMOVE DUPLICATES; SELECT * FROM target; id | name ---+------------ 30 | Tony 11 | Alice 23 | David 22 | Clarence (4 rows)

次の例は、source_table に一致する行がある場合に、target_table から重複する行を削除する、REMOVE DUPLICATES 句を使用した MERGE コマンドの簡素化された構文を示しています。

CREATE TABLE target (id INT, name CHAR(10)); CREATE TABLE source (id INT, name CHAR(10)); INSERT INTO target VALUES (30, 'Tony'), (30, 'Daisy'), (11, 'Alice'), (23, 'Bill'), (23, 'Nikki'); INSERT INTO source VALUES (23, 'David'), (22, 'Clarence'); MERGE INTO target USING source ON target.id = source.id REMOVE DUPLICATES; SELECT * FROM target; id | name ---+------------ 30 | Tony 30 | Daisy 11 | Alice 23 | David 22 | Clarence (5 rows)

MERGE の実行後、target_table には ID 値 23 の行が 1 つのみになります。source_table には ID 値 30 の行がなかったため、target_table には ID 値 30 の 2 つの重複行が残ります。

以下も参照してください。

INSERT, UPDATE, DELETE