MERGE - Amazon Redshift

MERGE

Fusiona de forma condicional las filas de una tabla de origen con una tabla de destino. Tradicionalmente, esto solo puede conseguirse utilizando varias sentencias de inserción, actualización o eliminación por separado. Para obtener más información sobre las operaciones que MERGE le permite combinar, consulte UPDATE, DELETE e INSERT.

Sintaxis

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 ]

Parámetros

target_table

La tabla temporal o permanente en la que se fusiona la instrucción MERGE.

source_table

Tabla temporal o permanente que proporciona las filas que se van a fusionar en target_table. source_table también puede ser una tabla de Spectrum.

alias

El nombre alternativo temporal de source_table.

Este parámetro es opcional. El alias anterior con AS también es opcional.

match_condition

Especifica los predicados iguales entre la columna de la tabla de origen y la columna de la tabla de destino que se utilizan para determinar si las filas de source_table pueden coincidir con las filas de target_table. Si se cumple la condición, MERGE ejecuta matched_clause para esa fila. De lo contrario, MERGE ejecuta not_matched_clause para esa fila.

WHEN MATCHED

Especifica la acción que se ejecutará cuando la condición de coincidencia entre una fila de origen y una fila de destino se evalúe como True. Puede especificar una acción UPDATE o una acción DELETE.

UPDATE

Actualiza la fila coincidente en target_table. Solo se actualizan los valores de col_name que especifique.

DELETE

Elimina la fila coincidente en target_table.

WHEN NOT MATCHED

Especifica la acción que se ejecutará cuando la condición de coincidencia se evalúe como False o Unknown. Solo puede especificar la acción de inserción INSERT para esta cláusula.

INSERT

Inserta en target_table filas de source_table que no coinciden con ninguna fila de target_table, según la condición de match_condition. El valor de col_name de destino puede enumerarse en cualquier orden. Si no proporciona ningún valor de col_name, el orden predeterminado será el de todas las columnas de la tabla en su orden declarado.

col_name

Una o más columnas que desea modificar. No incluya el nombre de la tabla al especificar la columna de destino.

expr

La expresión que define el nuevo valor de col_name.

REMOVE DUPLICATES

Especifica que el comando MERGE se ejecuta en modo simplificado. El modo simplificado tiene los siguientes requisitos:

  • target_table y source_table deben tener el mismo número de columnas y tipos de columna compatibles.

  • Omita la cláusula WHEN y las cláusulas UPDATE e INSERT de su comando MERGE.

  • Utilice la cláusula REMOVE DUPLICATES en su comando MERGE.

En el modo simplificado, MERGE hace lo siguiente:

  • Las filas de target_table que tienen una coincidencia en source_table se actualizan para que coincidan con los valores de source_table.

  • Las filas de source_table que no tengan una coincidencia en target_table se insertan en target_table.

  • Cuando varias filas de target_table coinciden con la misma fila de source_table, se eliminan las filas duplicadas. Amazon Redshift mantiene una fila y la actualiza. Las filas duplicadas que no coinciden con una fila de source_table permanecen sin cambios.

El uso de REMOVE DUPLICATES ofrece mejor rendimiento que usar WHEN MATCHED y WHEN NOT MATCHED. Recomendamos utilizar REMOVE DUPLICATES si target_table y source_table son compatibles y no necesita conservar filas duplicadas en target_table.

Notas de uso

  • Para ejecutar instrucciones MERGE, debe ser el propietario tanto de source_table como de target_table o tener el permiso SELECT para esas tablas. Además, debe tener los permisos UPDATE, DELETE e INSERT para target_table, según las operaciones incluidas en la instrucción MERGE.

  • target_table no puede ser una tabla del sistema, una tabla de catálogo ni una tabla externa.

  • source_table y target_table no pueden ser la misma tabla.

  • No se puede utilizar la cláusula WITH en una instrucción MERGE.

  • Las filas de target_table no pueden coincidir con varias filas de source_table.

    Considere el siguiente ejemplo:

    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.

    En ambas instrucciones MERGE, se produce un error en la operación porque hay varias filas en la tabla source con un valor de ID de 1.

  • match_condition y expr no pueden hacer referencia de forma parcial a columnas de tipo SUPER. Por ejemplo, si el objeto de tipo SUPER es una matriz o una estructura, no puede usar elementos individuales de esa columna para match_condition ni expr, pero puede usar toda la columna.

    Considere el siguiente ejemplo:

    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.

    Para obtener más información sobre el tipo SUPER, consulte Tipo SUPER.

  • Si source_table es grande, definir las columnas de combinación de target_table y source_table como claves de distribución puede mejorar el rendimiento.

  • Para utilizar la cláusula REMOVE DUPLICATES, necesita permisos SELECT, INSERT y DELETE para target_table.

  • source_table puede ser una vista o una subconsulta. A continuación, se muestra un ejemplo de una instrucción MERGE en la que source_table es una subconsulta que elimina las filas duplicadas.

    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);
  • El destino no puede ser un origen de datos de ninguna subconsulta de la misma instrucción MERGE. Por ejemplo, el siguiente comando SQL devuelve un error como ERROR: Source view/subquery in Merge statement cannot reference target table. porque la subconsulta hace referencia a target en vez de a source.

    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);

Ejemplos

En el siguiente ejemplo, se crean dos tablas y, a continuación, se ejecuta una operación MERGE en ellas, se actualizan las filas coincidentes de la tabla de destino y se insertan las filas que no coinciden. A continuación, inserta otro valor en la tabla de origen y ejecuta otra operación MERGE, esta vez se eliminan las filas coincidentes y se inserta la nueva fila de la tabla de origen.

Primero cree y rellene las tablas de origen y destino.

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)

A continuación, fusione la tabla de origen con la de destino, actualice la tabla de destino con las filas coincidentes e inserte las filas de la tabla de origen que no coincidan.

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)

Tenga en cuenta que las filas con valores de identificación (id) de 102 y 103 se actualizan para que coincidan con los valores de nombre (name) de la tabla de destino. Además, se inserta una nueva fila con un valor de identificación de 104 y el valor de nombre de Bill en la tabla de destino.

A continuación, inserte una nueva fila en la tabla de origen.

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

Por último, ejecute una operación de fusión para eliminar las filas coincidentes de la tabla de destino e insertar las filas que no coincidan.

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)

Las filas con los valores de identificación 102, 103 y 104 se eliminan de la tabla de destino y se inserta una nueva fila con un valor de identificación de 105 y un valor de nombre de David en la tabla de destino.

En el siguiente ejemplo, se muestra la sintaxis simplificada de un comando MERGE que utiliza la cláusula REMOVE DUPLICATES.

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)

En el siguiente ejemplo, se muestra la sintaxis simplificada de un comando MERGE que utiliza la cláusula REMOVE DUPLICATES, lo que elimina las filas duplicadas de target_table si tienen filas coincidentes en source_table.

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)

Después de ejecutar MERGE, solo hay una fila con un valor de ID de 23 en target_table. Como no había ninguna fila en source_table con el valor de ID 30, las dos filas duplicadas con valores de ID 30 permanecen en target_table.

Véase también

INSERT, UPDATE, DELETE