

 Amazon Redshift non supporterà più la creazione di nuovi Python UDFs a partire dalla Patch 198. Python esistente UDFs continuerà a funzionare fino al 30 giugno 2026. Per ulteriori informazioni, consulta il [post del blog](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/). 

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Aggiornamento e inserimento di nuovi dati
<a name="t_updating-inserting-using-staging-tables-"></a>

È possibile aggiungere in modo efficiente nuovi dati a una tabella esistente utilizzando il comando MERGE. Eseguite un'operazione di unione creando una tabella intermedia e quindi utilizzando uno dei metodi descritti in questa sezione per aggiornare la tabella di destinazione dalla tabella intermedia. Per ulteriori informazioni sul comando MERGE, consulta [MERGE](r_MERGE.md).

Gli [Esempi di unione](merge-examples.md) utilizzano un set di dati di esempio per Amazon Redshift, chiamato TICKIT. Come prerequisito, puoi configurare le tabelle e i dati TICKIT seguendo le istruzioni disponibili in [Nozioni di base sulle attività di database comuni](https://docs.aws.amazon.com/redshift/latest/gsg/database-tasks.html). Informazioni più dettagliate sul set di dati di esempio sono disponibili in [Database di esempio](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html). 

## Metodo di unione 1: sostituzione di righe esistenti
<a name="merge-method-replace-existing-rows"></a>

Se si sovrascrivono tutte le colonne della tabella di destinazione, il metodo più veloce per eseguire un'unione consiste nel sostituire le righe esistenti. Questa operazione effettua la scansione della tabella di destinazione solo una volta, utilizzando un inner join per eliminare le righe che verranno aggiornate. Una volta eliminate le righe, vengono sostituite insieme alle nuove righe da una singola operazione INSERT dalla tabella di gestione temporanea. 

Utilizza questo metodo se tutte le seguenti condizioni sono vere: 
+ La tabella di destinazione e la tabella di gestione temporanea contengono le stesse colonne. 
+ Intendi sostituire tutti i dati nelle colonne della tabella di destinazione con tutte le colonne della tabella di gestione temporanea.
+ Utilizzerai tutte le righe nella tabella di gestione temporanea nell'unione.

Se uno qualsiasi di questi criteri non si applica, utilizza il Metodo di unione 2: specifica di un elenco di colonne con MERGE, descritto nella sezione seguente.

Se non utilizzi tutte le righe nella tabella di gestione temporanea, è possibile filtrare le istruzioni DELETE e INSERT tramite una clausola WHERE per escludere le righe di cui non è effettivamente in corso la modifica. Tuttavia, se la maggior parte delle righe nella tabella di gestione temporanea non verrà inclusa nell'unione, consigliamo di eseguire un UPDATE e un INSERT in fasi separate, come descritto più avanti in questa sezione.

## Metodo di unione 2: specifica di un elenco di colonne senza usare MERGE
<a name="merge-method-specify-column-list"></a>

Utilizza questo metodo per aggiornare colonne specifiche nella tabella di destinazione anziché sovrascrivere intere righe. Questo metodo richiede più tempo del metodo precedente perché richiede una fase di aggiornamento aggiuntiva e non usa il comando MERGE. Utilizza questo metodo se una delle seguenti condizioni è vera: 
+ Non tutte le colonne nella tabella di destinazione devono essere aggiornate. 
+ La maggior parte delle righe nella tabella di gestione temporanea non verrà utilizzata negli aggiornamenti. 

**Topics**
+ [Metodo di unione 1: sostituzione di righe esistenti](#merge-method-replace-existing-rows)
+ [Metodo di unione 2: specifica di un elenco di colonne senza usare MERGE](#merge-method-specify-column-list)
+ [Creazione di una tabella di gestione temporanea](merge-create-staging-table.md)
+ [Esecuzione di un'operazione di unione tramite sostituzione di righe esistenti](merge-replacing-existing-rows.md)
+ [Esecuzione di un'operazione di unione tramite specificazione di un elenco di colonne senza l'uso del comando MERGE](merge-specify-a-column-list.md)
+ [Esempi di unione](merge-examples.md)

# Creazione di una tabella di gestione temporanea
<a name="merge-create-staging-table"></a>

La *tabella di gestione temporanea* è una tabella temporanea che contiene tutti i dati che verranno utilizzati per apportare modifiche alla *tabella di destinazione*, inclusi gli aggiornamenti e gli inserimenti. 

Un'operazione di unione richiede un join tra la tabella di gestione temporanea e la tabella di destinazione. Per collocare le righe di unione, imposta la chiave di distribuzione della tabella di gestione temporanea sulla stessa colonna della chiave di distribuzione della tabella di destinazione. Ad esempio, se la tabella di destinazione utilizza una colonna chiave esterna come chiave di distribuzione, utilizza la stessa colonna per la chiave di distribuzione della tabella di gestione temporanea. Se crei una tabella di gestione temporanea tramite un'istruzione [CREATE TABLE LIKE](r_CREATE_TABLE_NEW.md#create-table-like), la tabella di gestione temporanea erediterà la chiave di distribuzione dalla tabella padre. Se utilizzi un'istruzione CREATE TABLE AS, la nuova tabella non eredita la chiave di distribuzione. Per ulteriori informazioni, consulta [Distribuzione dei dati per l’ottimizzazione delle query](t_Distributing_data.md)

Se la chiave di distribuzione non è uguale alla chiave primaria e la chiave di distribuzione non viene aggiornata come parte dell'operazione di unione, aggiungi un predicato di join ridondante alle colonne della chiave di distribuzione per abilitare un join collocato. Ad esempio: 

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

Per verificare che la query utilizzerà un join collocato, esegui la query con [EXPLAIN](r_EXPLAIN.md) e controlla DS\$1DIST\$1NONE su tutti i join. Per ulteriori informazioni, consulta [Valutazione del piano di query](c_data_redistribution.md)

# Esecuzione di un'operazione di unione tramite sostituzione di righe esistenti
<a name="merge-replacing-existing-rows"></a>

Quando esegui l'operazione di unione descritta nella procedura, inserisci tutti i passaggi, tranne la creazione e l'eliminazione della tabella di gestione temporanea, in un'unica transazione. Verrà eseguito il rollback della transazione se una fase restituisce un errore. L'utilizzo di una singola transazione riduce anche il numero di commit, risparmiando tempo e risorse.

**Per eseguire un'operazione di unione tramite sostituzione di righe esistenti**

1. Creare una tabella di gestione temporanea e quindi popolarla con i dati da unire, come mostrato nel seguente pseudocodice.

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

1.  Utilizzate MERGE per eseguire un'unione interna con la tabella intermedia per aggiornare le righe della tabella di destinazione che corrispondono alla tabella intermedia, quindi inserite tutte le righe rimanenti nella tabella di destinazione che non corrispondono alla tabella intermedia.

    Ti consigliamo di eseguire le operazioni di aggiornamento e inserimento in un unico 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. Rilasciare la tabella di gestione temporanea. 

   ```
   DROP TABLE stage;
   ```

# Esecuzione di un'operazione di unione tramite specificazione di un elenco di colonne senza l'uso del comando MERGE
<a name="merge-specify-a-column-list"></a>

Quando esegui l'operazione di unione descritta nella procedura, inserisci tutti i passaggi in un'unica transazione. Verrà eseguito il rollback della transazione se una fase restituisce un errore. L'utilizzo di una singola transazione riduce anche il numero di commit, risparmiando tempo e risorse.

**Per eseguire un'operazione di unione tramite specificazione di un elenco di colonne**

1. Inserisci l'intera operazione in un unico blocco di transazioni. 

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

1. Creare una tabella di gestione temporanea e quindi popolarla con i dati da unire, come mostrato nel seguente pseudocodice. 

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

1. Aggiornare la tabella di destinazione tramite un inner join con la tabella di gestione temporanea. 
   + Nella clausola UPDATE, elencare in modo esplicito le colonne da aggiornare. 
   + Eseguire un inner join con la tabella di gestione temporanea. 
   + Se la chiave di distribuzione è diversa dalla chiave primaria e la chiave di distribuzione non viene aggiornata, aggiungere un predicato di join ridondante alle colonne della chiave di distribuzione per abilitare un join collocato. Per verificare che la query utilizzerà un join collocato, esegui la query con [EXPLAIN](r_EXPLAIN.md) e controlla DS\$1DIST\$1NONE su tutti i join. Per ulteriori informazioni, consulta [Valutazione del piano di query](c_data_redistribution.md)
   + Se la tabella di destinazione è ordinata per timestamp, aggiungere un predicato per sfruttare le scansioni a intervallo limitato nella tabella di destinazione. Per ulteriori informazioni, consulta [Best practice di Amazon Redshift per la progettazione di query](c_designing-queries-best-practices.md).
   + Se non utilizzi tutte le righe nell'unione, aggiungi una clausola per filtrare le righe che desideri modificare. Ad esempio, aggiungere un filtro disuguaglianza a una o più colonne per escludere le righe che non sono state modificate.
   + Inserire le operazioni di aggiornamento, eliminazione e inserimento in un singolo blocco di transazione, in modo che in caso di problemi venga eseguito il rollback.

    Ad esempio: 

   ```
   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. Eliminare le righe non necessarie dalla tabella di gestione temporanea tramite un inner join con la tabella di destinazione. Alcune righe nella tabella di destinazione corrispondono già alle righe corrispondenti nella tabella di gestione temporanea e altre sono state aggiornate nella fase precedente. In entrambi i casi, non sono necessarie per l'inserimento. 

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

1. Inserire tutte le righe rimanenti dalla tabella di gestione temporanea. Utilizzare lo stesso elenco di colonne nella clausola VALUES utilizzato nell'istruzione UPDATE nella fase due. 

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

1. Rilasciare la tabella di gestione temporanea. 

   ```
   drop table stage;
   ```

# Esempi di unione
<a name="merge-examples"></a>

Negli esempi seguenti viene eseguita un'unione per aggiornare la tabella SALES. Il primo esempio utilizza il metodo più semplice di eliminazione dalla tabella di destinazione e quindi l'inserimento di tutte le righe dalla tabella di gestione temporanea. La seconda fase richiede l'aggiornamento su colonne selezionate nella tabella di destinazione, quindi include una fase di aggiornamento aggiuntiva. 

Gli [Esempi di unione](#merge-examples) utilizzano un set di dati di esempio per Amazon Redshift, chiamato TICKIT. Come prerequisito, puoi configurare le tabelle e i dati TICKIT seguendo le istruzioni disponibili in [Nozioni di base sulle attività di database comuni](https://docs.aws.amazon.com/redshift/latest/gsg/database-tasks.html). Informazioni più dettagliate sul set di dati di esempio sono disponibili in [Database di esempio](https://docs.aws.amazon.com/redshift/latest/dg/c_sampledb.html). 

**Origine dati di unione di esempio**

Gli esempi in questa sezione richiedono un'origine dati di esempio che includa sia gli aggiornamenti sia gli inserimenti. Per gli esempi, creeremo una tabella di esempio denominata SALES\$1UPDATE che utilizza i dati dalla tabella SALES. Popoleremo la nuova tabella con dati casuali che rappresentano nuove attività di vendita per dicembre. Utilizzeremo la tabella di esempio SALES\$1UPDATE per creare la tabella di gestione temporanea negli esempi che seguono. 

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

**Esempio di un'unione che sostituisce le righe esistenti in base alle chiavi di corrispondenza**

Il seguente script utilizza la tabella SALES\$1UPDATE per eseguire un'operazione di unione nella tabella SALES con nuovi dati per l'attività di vendita di dicembre. Questo esempio sostituisce le righe della tabella SALES che contengono aggiornamenti. Per questo esempio, vogliamo aggiornare le colonne QTYSOLD e PRICEPAID e non modificare COMMISSION e 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);
```

**Esempio di un'unione che specifica un elenco di colonne senza usare MERGE**

L'esempio seguente esegue un'operazione di unione per aggiornare SALES con i nuovi dati per l'attività di vendita di dicembre. Sono necessari dati di esempio che includano sia gli aggiornamenti sia gli inserimenti, oltre alle righe che non sono state modificate. Per questo esempio, vogliamo aggiornare le colonne QTYSOLD e PRICEPAID e non modificare COMMISSION e SALETIME. Il seguente script utilizza la tabella SALES\$1UPDATE per eseguire un'operazione di unione nella tabella 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;
```