Aggiorna la tabella utilizzando i valori di un'altra tabella in SQL Server


13

Ho 2 tabella nel mio database.

Tabella 1

-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address | birthdate |
-------------------------------------------------------------------------

Tavolo 2

-----------------------------------------
| gender | address | phone | birthdate |
-----------------------------------------

nelle colonne della tabella n. 1 indirizzo e phone2 sono vuoti e i valori di genere e data di nascita delle colonne sono gli stessi della tabella n. 2.

Come posso leggere i dati dalla tabella # 2 e aggiornare l' indirizzo e phone2 nella tabella # 1 con i valori dell'indirizzo della tabella # 2 e le colonne del telefono quando genere e data di nascita sono gli stessi in ogni riga?

per esempio: questi sono alcuni dati nella Tabella n. 1

-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address | birthdate |
-------------------------------------------------------------------------
| john | doe    | 12345| t@t.com| Male  |         |         | 1980-01-01|
-------------------------------------------------------------------------
| mike | clark  | 65432| x@y.com| Male  |         |         | 1990-01-01|
-------------------------------------------------------------------------
| Sara | King   | 875465| a@b.com|Female|         |         | 1970-01-01|
-------------------------------------------------------------------------

e qui ci sono alcuni dati nella tabella # 2

-----------------------------------------
| gender | address | phone | birthdate  |
-----------------------------------------
| Male   | 1704test|0457852|1980-01-01  |
-----------------------------------------
| Female | 1705abcs|0986532|1970-01-01  |
-----------------------------------------
| Male   | 1602cyzd|0326589|1990-01-01  |
-----------------------------------------

Voglio aggiornare la tabella n. 1 con i dati della tabella n. 2 e controllare il genere e la data di nascita e rendere la tabella n. 1 simile

-------------------------------------------------------------------------
| name | family | phone | email | gender | phone2 | address | birthdate |
-------------------------------------------------------------------------
| john | doe    | 12345| t@t.com| Male   |0457852 |1704test | 1980-01-01|
-------------------------------------------------------------------------
| mike | clark  | 65432| x@y.com| Male   |0326589  |1602cyzd| 1990-01-01|
-------------------------------------------------------------------------
| Sara | King   | 875465| a@b.com|Female |0986532  |1705abcs| 1970-01-01|
-------------------------------------------------------------------------

Come posso fare questo?


1
E se ci fossero 2 o più persone con lo stesso sesso e la stessa data di nascita? Quale telefono e indirizzo (tra i tanti) dovrebbero essere copiati?
ypercubeᵀᴹ

non è possibile, questa è solo una tabella di test, nei miei dati reali non è possibile per la stessa persona avere gli stessi valori.
John Doe,

Se non è davvero possibile, ovvero se è presente un UNIQUEvincolo table2 (gender, birthdate), è necessario aggiungere tali informazioni alla domanda.
ypercubeᵀᴹ

Risposte:


26

Esistono diversi modi per ottenere i risultati desiderati.

Metodi non deterministici

(nel caso in cui molte righe nella tabella 2 corrispondano a una nella tabella 1)

UPDATE T1
SET    address = T2.address,
       phone2 = T2.phone
FROM   #Table1 T1
       JOIN #Table2 T2
         ON T1.gender = T2.gender
            AND T1.birthdate = T2.birthdate

O una forma leggermente più concisa

UPDATE #Table1
SET    address = #Table2.address,
       phone2 = #Table2.phone
FROM   #Table2
WHERE  #Table2.gender = #Table1.gender
       AND #Table2.birthdate = #Table1.birthdate 

O con un CTE

WITH CTE
     AS (SELECT T1.address AS tgt_address,
                T1.phone2  AS tgt_phone,
                T2.address AS source_address,
                T2.phone   AS source_phone
         FROM   #Table1 T1
                INNER JOIN #Table2 T2
                  ON T1.gender = T2.gender
                     AND T1.birthdate = T2.birthdate)
UPDATE CTE
SET    tgt_address = source_address,
       tgt_phone = source_phone 

Metodi deterministici

MERGE genererebbe un errore anziché accettare risultati non deterministici

MERGE #Table1 T1
USING #Table2 T2
ON T1.gender = T2.gender
   AND T1.birthdate = T2.birthdate
WHEN MATCHED THEN
  UPDATE SET address = T2.address,
             phone2 = T2.phone; 

Oppure potresti scegliere un record specifico se c'è più di una partita

Con APPLY

UPDATE T1
SET    address = T2.address,
       phone2 = T2.phone
FROM   #Table1 T1
       CROSS APPLY (SELECT TOP 1 *
                    FROM   #Table2 T2
                    WHERE  T1.gender = T2.gender
                           AND T1.birthdate = T2.birthdate
                    ORDER  BY T2.PrimaryKey) T2 

.. O un CTE

WITH T2
     AS (SELECT *,
                ROW_NUMBER() OVER (PARTITION BY gender, birthdate ORDER BY primarykey) AS RN
         FROM   #Table2)
UPDATE T1
SET    address = T2.address,
       phone2 = T2.phone
FROM   #Table1 T1
       JOIN T2
         ON T1.gender = T2.gender
            AND T1.birthdate = T2.birthdate
            AND T2.RN = 1;

Grazie per il tuo ottimo aiuto! Ho 2 domande: 1) Penso che sia un modo semplice per farlo, penso che questo sia ridurre le prestazioni e se ho circa 50milion di record in questo modo è molto lento, sei d'accordo? 2) in questo modo, se voglio unire 2table e alcune colonne nella tabella # 2 non esistono nella tabella # 1 ho riscontrato qualche errore? per esempio se ho una colonna di colore nella tabella # 2 e non esiste nella tabella # 1, il processo di join ha errore o solo le colonne di join esistono in 2tables? Grazie ancora ...
John Doe

1
@John: Se hai una domanda sulle prestazioni, fai una nuova domanda e fornisci i dettagli delle dimensioni, delle strutture, degli indici e dei piani di esecuzione della tabella. Non capisco cosa stai chiedendo al punto 2, modifica la tua domanda e fornisci strutture di tabelle di esempio che dimostrino il problema che stai ponendo.
Martin Smith,

1
@JohnDoe: se intendi per colonna intendi un valore di colonna (in altre parole, una riga corrispondente ) - quando non c'è riga corrispondente, non viene generato alcun errore. Nel caso di un join interno (come qui), le righe non corrispondenti non verranno aggiornate, ma se in realtà intendevi una colonna che esiste in una tabella e non esiste nell'altra, allora credo che sia una più nuova domanda da porre separatamente.
Andriy M,

Su quel primo CTE, come fa SQL Server a sapere quale tabella aggiornare?
Ron John

@RonJohn Conosce l'origine delle colonne. vale a dire che entrambi tgt_addresse tgt_phonesono alias per le colonne in #Table1- quindi questa è la destinazione per l'aggiornamento.
Martin Smith,

0
UPDATE TS
SET TS.TaskFullAddress = L.FullAddress
FROM [dbo].[TaskOrders]   TS
INNER JOIN Locations L
ON  TS.ClientId  = L.ClientId;

I nomi dei campi nella risposta non corrispondono ai nomi dei campi nella domanda, ma la tecnica funziona.
Ron John

Grazie Ron, sto solo dando l'idea
David Fawzy,

Si tratta , però, perché la vostra risposta è stata bocciata.
Ron John

Grazie, non sono sicuro, poiché ho copiato il codice funzionava nella mia applicazione live
David Fawzy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.