

 Amazon Redshift は、パッチ 198 以降、新しい Python UDF の作成をサポートしなくなります。既存の Python UDF は、2026 年 6 月 30 日まで引き続き機能します。詳細については、[ブログ記事](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)を参照してください。

# MERGE
<a name="r_MERGE"></a>

ソーステーブルの行を条件付きでターゲットテーブルにマージします。従来、これは複数の insert、update、delete ステートメントを別々に使用することによってのみ実現していました。MERGE で組み合わせることができる操作の詳細については、「[UPDATE](https://docs.aws.amazon.com/redshift/latest/dg/r_UPDATE.html)」、「[DELETE](https://docs.aws.amazon.com/redshift/latest/dg/r_DELETE.html)」、「[INSERT](https://docs.aws.amazon.com/redshift/latest/dg/r_INSERT_30.html)」を参照してください。

## 構文
<a name="r_MERGE-synopsis"></a>

```
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 ]
```

## パラメータ
<a name="r_MERGE-parameters"></a>

 *target\$1table*  
MERGE ステートメントがマージされる一時または永続テーブル。

 *source\$1table*  
target\$1table にマージする行を提供する一時または永続テーブル。source\$1table は、Spectrum テーブルにすることもできます。****

 *alias*  
*source\$1table* の一時的な代替名。  
このパラメータはオプションです。*alias* の先頭に AS を付けることもできます。

 *match\$1condition*  
ソーステーブルの列とターゲットテーブルの列の間に等しい述語を指定します。これを使用して、*source\$1table* の行が *target\$1table* の行と一致するかどうかを判断します。条件が満たされると、MERGE はその行に対して *matched\$1clause* を実行します。それ以外の場合は、MERGE はその行に対して *not\$1matched\$1clause* を実行します。

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

UPDATE  
 *target\$1table* 内の一致した行を更新します。指定した *col\$1name* の値のみが更新されます。

DELETE  
 *target\$1table* 内の一致した行を削除します。

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

INSERT  
 match\$1condition に従って、target\$1table のどの行とも一致しない source\$1table の target\$1table 行に挿入します。********ターゲットの *col\$1name* は、任意の順序でリストできます。*col\$1name* の値を指定しない場合、デフォルトの順序は、テーブルのすべての列が宣言した順序になります。

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

 *\$1 expr*  
*col\$1name* の新しい値を定義する式。

 REMOVE DUPLICATES  
MERGE コマンドを簡易モードで実行することを指定します。簡易モードには次の要件があります。  
+  *target\$1table* と *source\$1table* は、列数が同じで、列タイプに互換性があり、列の順序が同じである必要があります。
+  MERGE コマンドから WHEN 句、UPDATE 句、INSERT 句を省略します。
+  MERGE コマンドで REMOVE DUPLICATES 句を使用します。
簡易モードの場合、MERGE は次の操作を行います。  
+  *source\$1table* と一致する *target\$1table* 内の行は、*source\$1table* の値と一致するように更新されます。
+  *target\$1table* と一致しない *source\$1table* 内の行は、*target\$1table* に挿入されます。
+  *target\$1table* 内の複数の行が *source\$1table* 内の同じ行と一致する場合、重複する行は削除されます。Amazon Redshift は 1 つの行を保持し、それを更新します。*source\$1table* 内の行と一致しない重複行は変更されません。
REMOVE DUPLICATES を使用すると、WHEN MATCHED や WHEN NOT MATCHED を使用するよりもパフォーマンスが向上します。*target\$1table* と *source\$1table* に互換性があり、*target\$1table* に重複業を保持する必要がない場合は、REMOVE DUPLICATES を使用することをお勧めします。

## 使用に関する注意事項
<a name="r_MERGE_usage_notes"></a>
+ MERGE ステートメントを実行するには、*source\$1table* と *target\$1table* の両方の所有者であるか、それらのテーブルの SELECT 権限を持っている必要があります。さらに、MERGE ステートメントに含まれるオペレーションに応じて、*target\$1table* の UPDATE、DELETE、および INSERT 権限が必要です。
+  *target\$1table* をシステムテーブル、カタログテーブル、または外部テーブルにすることはできません。
+  *source\$1table* と *target\$1table* を同じテーブルにすることはできません。
+  MERGE ステートメントで WITH 句を使用することはできません。
+  *target\$1table* 内の行を *source\$1table* 内の複数の行と一致させることはできません。

  次の例を考えます。

  ```
  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 値が `1` の `source` テーブルに複数の行があるため、どちらの MERGE ステートメントでも操作は失敗します。
+  *match\$1condition* と *expr* はSUPER 型の列を部分的に参照することはできません。例えば、SUPER 型のオブジェクトが配列または構造体である場合、その列の個々の要素を *match\$1condition* や *expr* に使用することはできませんが、列全体を使用することはできます。

  次の例を考えます。

  ```
  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 型](https://docs.aws.amazon.com/redshift/latest/dg/r_SUPER_type.html)」を参照してください。
+ *source\$1table* が大きい場合は、*target\$1table* と *source\$1table* の両方の結合列を分散キーとして定義するとパフォーマンスが向上する可能性があります。
+ REMOVE DUPLICATES 句を使用するには、*target\$1table* に対する SELECT、INSERT、および DELETE アクセス許可が必要です。
+  source\$1table はビューまたはサブクエリです。**次に、source\$1table が重複する行を削除するサブクエリである 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);
  ```
+ ターゲットを、同じ MERGE ステートメントのサブクエリのデータソースにすることはできません。例えば、次の SQL コマンドの場合、サブクエリが `source` でなく `target` を参照しているため、「ERROR: Source view/subquery in Merge statement cannot reference target table」(エラー: Merge ステートメントのソースのビューまたはサブクエリはターゲットテーブルを参照できません) というエラーが返されます。

  ```
  MERGE INTO target
  USING (SELECT id, name FROM target 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);
  ```

## 例
<a name="sub-examples-merge"></a>

次の例では、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\$1table に一致する行がある場合に、target\$1table から重複する行を削除する、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\$1table* には ID 値 23 の行が 1 つのみになります。*source\$1table* には ID 値 30 の行がなかったため、*target\$1table* には ID 値 30 の 2 つの重複行が残ります。

## 関連情報
<a name="r_MERGE-see-also"></a>

 [INSERT](r_INSERT_30.md), [UPDATE](r_UPDATE.md), [DELETE](r_DELETE.md) 