

 Amazon Redshift dejará de admitir la creación de nuevas UDF de Python a partir del parche 198. Las UDF de Python existentes seguirán funcionando hasta el 30 de junio de 2026. Para obtener más información, consulte la [publicación del blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

# Actualización e inserción de datos nuevos
<a name="t_updating-inserting-using-staging-tables-"></a>

Puede agregar eficazmente nuevos datos a una tabla existente mediante el comando MERGE. Realice una operación de fusión mediante la creación de una tabla provisional y, a continuación, utilice uno de los métodos descritos en esta sección para actualizar la tabla de destino a partir de la tabla provisional. Para obtener más información sobre el comando MERGE, consulte [MERGE](r_MERGE.md).

En los [Ejemplos de fusión](merge-examples.md) se usa un conjunto de datos de muestra para Amazon Redshift, denominado conjunto de datos TICKIT. Como requisito previo, puede configurar las tablas y los datos de TICKIT según las instrucciones disponibles en [Introducción a tareas comunes de bases de datos](https://docs.aws.amazon.com/redshift/latest/gsg/database-tasks.html). Encontrará información más detallada sobre el conjunto de datos de muestra en [Base de datos de muestra](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html). 

## Método de fusión 1: Reemplazar filas existentes
<a name="merge-method-replace-existing-rows"></a>

Si sobrescribe todas las columnas de la tabla de destino, el método más rápido para realizar una combinación es sustituir las filas existentes. Esto escanea la tabla de destino solo una vez, mediante una combinación interna para eliminar las filas que se actualizarán. Una vez eliminadas las filas, se reemplazan por filas nuevas mediante una operación de inserción única desde la tabla provisional. 

Aplique este método si se satisfacen todas las siguientes condiciones: 
+ La tabla destino y la provisional tienen las mismas columnas. 
+ Desea reemplazar todos los datos de las columnas de la tabla destino por los de las columnas de la tabla provisional.
+ Usará todas las filas de la tabla provisional en la fusión.

Si alguno de estos criterios no se aplica, utilice el Método de fusión 2: especificación de una lista de columnas sin utilizar MERGE, descrito en la siguiente sección.

Si no usará todas las filas de la tabla provisional, filtre las instrucciones DELETE e INSERT al usar una cláusula WHERE para excluir las filas que no cambiarán. No obstante, si la mayoría de las filas de la tabla provisional no participarán en la fusión, recomendamos ejecutar los comandos UPDATE e INSERT en distintos pasos, según se describe posteriormente en esta sección.

## Método de fusión 2: especificación de una lista de columnas sin utilizar MERGE
<a name="merge-method-specify-column-list"></a>

Aplique este método para actualizar columnas específicas de la tabla destino, en lugar de sobrescribir filas enteras. Este método tarda más que el anterior porque requiere un paso de actualización adicional y no utiliza el comando MERGE. Aplique este método si se satisface alguna de las siguientes condiciones: 
+ No todas las columnas de la tabla destino se actualizarán. 
+ La mayoría de las filas de la tabla provisional no se usarán en las actualizaciones. 

**Topics**
+ [Método de fusión 1: Reemplazar filas existentes](#merge-method-replace-existing-rows)
+ [Método de fusión 2: especificación de una lista de columnas sin utilizar MERGE](#merge-method-specify-column-list)
+ [Creación de una tabla provisional temporal](merge-create-staging-table.md)
+ [Realización de una operación de fusión al reemplazar filas existentes](merge-replacing-existing-rows.md)
+ [Realización de una operación de fusión al especificar una lista de columnas sin usar el comando MERGE](merge-specify-a-column-list.md)
+ [Ejemplos de fusión](merge-examples.md)

# Creación de una tabla provisional temporal
<a name="merge-create-staging-table"></a>

La *tabla provisional* es una tabla temporal que tiene todos los datos que se usarán para hacer los cambios en la *tabla de destino*, incluidas las actualizaciones e inserciones. 

Una operación de fusión requiere una combinación entre la tabla provisional y la tabla destino. Para colocar las filas de combinación, establezca la clave de distribución de la tabla provisional en la misma columna que la clave de distribución de la tabla destino. Por ejemplo, si la tabla destino usa una columna de clave externa como su clave de distribución, use la misma columna para la clave de distribución de la tabla provisional. Si crea la tabla provisional mediante una instrucción [CREATE TABLE LIKE](r_CREATE_TABLE_NEW.md#create-table-like), la tabla provisional heredará la clave de distribución de la tabla principal. Si usa una instrucción CREATE TABLE AS, la tabla nueva no hereda la clave de distribución. Para obtener más información, consulte [Distribución de datos para la optimización de consultas](t_Distributing_data.md)

Si la clave de distribución no es igual a la clave primaria y si no se actualiza como parte de la operación de fusión, agregue un predicado de combinación redundante en las columnas de la clave de distribución para permitir una combinación colocada. Por ejemplo: 

```
where target.primarykey = stage.primarykey 
and target.distkey = stage.distkey
```

Para corroborar que la consulta usará una combinación colocada, ejecute la consulta con [EXPLAIN](r_EXPLAIN.md) y, luego, controle la presencia de DS\$1DIST\$1NONE en todas las combinaciones. Para obtener más información, consulte [Evaluación del plan de consulta](c_data_redistribution.md)

# Realización de una operación de fusión al reemplazar filas existentes
<a name="merge-replacing-existing-rows"></a>

Cuando ejecute la operación de fusión detallada en el procedimiento, ponga todos los pasos, excepto la creación y eliminación de la tabla provisional, en una transacción única. La transacción se anula si se produce un error en algún paso. El uso de una transacción única también reduce la cantidad de confirmaciones, lo cual ahorra tiempo y recursos.

**Pasos para realizar una operación de fusión al reemplazar filas existentes**

1. Cree una tabla provisional y, luego, complétela con los datos que se fusionarán, como se muestra en el siguiente pseudocódigo.

   ```
   CREATE temp table stage (like target); 
   
   INSERT INTO stage 
   SELECT * FROM source 
   WHERE source.filter = 'filter_expression';
   ```

1.  Utilice MERGE para realizar una unión interna con la tabla provisional para actualizar las filas de la tabla de destino que coincidan con la tabla provisional y, a continuación, inserte en la tabla de destino todas las filas restantes que no coincidan con la tabla provisional.

    Le recomendamos que ejecute las operaciones de actualización e inserción en un único comando MERGE.

   ```
   MERGE INTO target 
   USING stage [optional alias] on (target.primary_key = stage.primary_key)
   WHEN MATCHED THEN 
   UPDATE SET col_name1 = stage.col_name1 , col_name2= stage.col_name2, col_name3 = {expr}
   WHEN NOT MATCHED THEN
   INSERT (col_name1 , col_name2, col_name3) VALUES (stage.col_name1, stage.col_name2, {expr});
   ```

1. Elimine la tabla provisional. 

   ```
   DROP TABLE stage;
   ```

# Realización de una operación de fusión al especificar una lista de columnas sin usar el comando MERGE
<a name="merge-specify-a-column-list"></a>

Cuando ejecute la operación de fusión detallada en el procedimiento, ponga todos los pasos en una transacción única. La transacción se anula si se produce un error en algún paso. El uso de una transacción única también reduce la cantidad de confirmaciones, lo cual ahorra tiempo y recursos.

**Pasos para realizar una operación de fusión al especificar una lista de columnas**

1. Coloque toda la operación en un único bloque de transacción. 

   ```
   BEGIN transaction;
   … 
   END transaction;
   ```

1. Cree una tabla provisional y, luego, complétela con los datos que se fusionarán, como se muestra en el siguiente pseudocódigo. 

   ```
   create temp table stage (like target); 
   insert into stage 
   select * from source 
   where source.filter = 'filter_expression';
   ```

1. Actualice la tabla destino mediante el uso de una combinación interna con la tabla provisional. 
   + En la cláusula UPDATE, especifique de manera explícita las columnas que se actualizarán. 
   + Realice una combinación interna con la tabla provisional. 
   + Si la clave de distribución es diferente a la clave primaria y si no se actualiza, agregue un predicado de combinación redundante en las columnas de la clave de distribución. Para corroborar que la consulta usará una combinación colocada, ejecute la consulta con [EXPLAIN](r_EXPLAIN.md) y, luego, controle la presencia de DS\$1DIST\$1NONE en todas las combinaciones. Para obtener más información, consulte [Evaluación del plan de consulta](c_data_redistribution.md)
   + Si la tabla de destino se ordena según la marca temporal, agregue un predicado para aprovechar los análisis de rango restringido en la tabla de destino. Para obtener más información, consulte [Prácticas recomendadas de Amazon Redshift para el diseño de consultas](c_designing-queries-best-practices.md).
   + Si no usará todas las filas en la fusión, agregue una cláusula para filtrar las filas que desea cambiar. Por ejemplo, agregue un filtro de desigualdad a una o más columnas para excluir las filas que no han cambiado.
   + Ponga las operaciones de actualización, eliminación e inserción en un bloque de transacción único de manera que, si se produce un problema, todo se revierta.

    Por ejemplo: 

   ```
   begin transaction;
   
   update target 
   set col1 = stage.col1, 
   col2 = stage.col2, 
   col3 = 'expression' 
   from stage 
   where target.primarykey = stage.primarykey 
   and target.distkey = stage.distkey 
   and target.col3 > 'last_update_time' 
   and (target.col1 != stage.col1 
   or target.col2 != stage.col2 
   or target.col3 = 'filter_expression');
   ```

1. Elimine las filas innecesarias de la tabla provisional mediante el uso de una combinación interna con la tabla destino. Algunas de las filas de la tabla destino ya coinciden con las filas correspondientes en la tabla provisional y otras se actualizaron en el paso anterior. En cualquiera de los casos, no se necesitan para la inserción. 

   ```
   delete from stage 
   using target 
   where stage.primarykey = target.primarykey;
   ```

1. Inserte las filas restantes desde la tabla provisional. Use la misma lista de columnas de la cláusula VALUES que usó en la instrucción UPDATE del paso dos. 

   ```
   insert into target
   (select col1, col2, 'expression'
   from stage);
   
   end transaction;
   ```

1. Elimine la tabla provisional. 

   ```
   drop table stage;
   ```

# Ejemplos de fusión
<a name="merge-examples"></a>

En los siguientes ejemplos, se realiza una fusión para actualizar la tabla SALES. En el primer ejemplo, se usa el método más simple de eliminar desde la tabla destino y, luego, se insertan todas las filas desde la tabla provisional. En el segundo ejemplo, se requiere la actualización de columnas seleccionadas de la tabla destino, por lo que se incluye un paso de actualización adicional. 

En los [Ejemplos de fusión](#merge-examples) se usa un conjunto de datos de muestra para Amazon Redshift, denominado conjunto de datos TICKIT. Como requisito previo, puede configurar las tablas y los datos de TICKIT siguiendo las instrucciones disponibles en [Introducción a las tareas comunes de bases de datos](https://docs.aws.amazon.com/redshift/latest/gsg/database-tasks.html). Encontrará información más detallada sobre el conjunto de datos de muestra en [Base de datos de muestra](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html). 

**Origen de datos de la fusión de muestra**

Los ejemplos de esta sección requieren de un origen de datos de muestra que incluye tanto actualizaciones como inserciones. Para los ejemplos, crearemos una tabla de muestra denominada SALES\$1UPDATE que usa datos de la tabla SALES. Llenaremos la tabla nueva con datos aleatorios que representan la actividad de ventas nueva para diciembre. Usaremos la tabla de muestra SALES\$1UPDATE para crear la tabla provisional de los ejemplos a continuación. 

```
-- Create a sample table as a copy of the SALES table.

create table tickit.sales_update as
select * from tickit.sales;

-- Change every fifth row to have updates.

update tickit.sales_update
set qtysold = qtysold*2,
pricepaid = pricepaid*0.8,
commission = commission*1.1
where saletime > '2008-11-30'
and mod(sellerid, 5) = 0;

-- Add some new rows to have inserts.
-- This example creates a duplicate of every fourth row.

insert into tickit.sales_update
select (salesid + 172456) as salesid, listid, sellerid, buyerid, eventid, dateid, qtysold, pricepaid, commission, getdate() as saletime
from tickit.sales_update
where saletime > '2008-11-30'
and mod(sellerid, 4) = 0;
```

**Ejemplo de una fusión que reemplaza filas existentes en las claves coincidentes**

El siguiente script usa la tabla SALES\$1UPDATE para realizar una operación de fusión en la tabla SALES con datos nuevos para la actividad de ventas de diciembre. En este ejemplo se reemplazan las filas de la tabla SALES que tienen actualizaciones. Para este ejemplo, actualizaremos las columnas qtysold y pricepaid, pero dejaremos sin cambios commission y saletime.

```
MERGE into tickit.sales 
USING tickit.sales_update sales_update  
on ( sales.salesid = sales_update.salesid
and sales.listid = sales_update.listid
and sales_update.saletime > '2008-11-30'
and (sales.qtysold != sales_update.qtysold 
or sales.pricepaid != sales_update.pricepaid))
WHEN MATCHED THEN
update SET qtysold = sales_update.qtysold,
pricepaid = sales_update.pricepaid
WHEN NOT MATCHED THEN 
INSERT (salesid, listid, sellerid, buyerid, eventid, dateid, qtysold , pricepaid, commission, saletime)
values (sales_update.salesid, sales_update.listid, sales_update.sellerid, sales_update.buyerid, sales_update.eventid, 
sales_update.dateid, sales_update.qtysold , sales_update.pricepaid, sales_update.commission, sales_update.saletime);

-- Drop the staging table.
drop table tickit.sales_update;

-- Test to see that commission and salestime were not impacted.
SELECT sales.salesid, sales.commission, sales.salestime, sales_update.commission, sales_update.salestime 
FROM tickit.sales 
INNER JOIN tickit.sales_update sales_update  
ON 
sales.salesid = sales_update.salesid
AND sales.listid = sales_update.listid
AND sales_update.saletime > '2008-11-30'
AND (sales.commission != sales_update.commission 
OR sales.salestime != sales_update.salestime);
```

**Ejemplo de fusión que especifica una lista de columnas sin utilizar MERGE**

En el siguiente ejemplo, se realiza una operación de fusión para actualizar la tabla SALES con datos nuevos para la actividad de ventas de diciembre. Necesitamos datos de muestra que incluyan tanto actualizaciones como inserciones, junto con filas que no hayan cambiado. Para este ejemplo, deseamos actualizar las columnas QTYSOLD y PRICEPAID, y dejar COMMISSION y SALETIME sin cambios. El siguiente script usa la tabla SALES\$1UPDATE para realizar una operación de fusión en la tabla SALES. 

```
-- Create a staging table and populate it with rows from SALES_UPDATE for Dec
create temp table stagesales as select * from sales_update
where saletime > '2008-11-30';

-- Start a new transaction
begin transaction;

-- Update the target table using an inner join with the staging table
-- The join includes a redundant predicate to collocate on the distribution key –- A filter on saletime enables a range-restricted scan on SALES

update sales
set qtysold = stagesales.qtysold,
pricepaid = stagesales.pricepaid
from stagesales
where sales.salesid = stagesales.salesid
and sales.listid = stagesales.listid
and stagesales.saletime > '2008-11-30'
and (sales.qtysold != stagesales.qtysold 
or sales.pricepaid != stagesales.pricepaid);
 
-- Delete matching rows from the staging table 
-- using an inner join with the target table

delete from stagesales
using sales
where sales.salesid = stagesales.salesid
and sales.listid = stagesales.listid;

-- Insert the remaining rows from the staging table into the target table
insert into sales
select * from stagesales;

-- End transaction and commit
end transaction;

-- Drop the staging table
drop table stagesales;
```