Actualizar tabla usando valores de otra tabla en SQL Server

13

Tengo 2 tablas en mi base de datos.

Tabla 1

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

Tabla 2

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

en la tabla # 1, la dirección de las columnas y el teléfono2 están vacíos y los valores de género y fecha de nacimiento de las columnas son los mismos que en la tabla # 2.

¿Cómo puedo leer los datos de la tabla # 2 y actualización de la dirección y phone2 en la tabla # 1 con valores de la tabla # 2 direcciones y teléfonos columnas al género y fecha de nacimiento es el mismo en cada fila?

por ejemplo: estos son algunos datos en la Tabla # 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|
-------------------------------------------------------------------------

y aquí hay algunos datos en la tabla # 2

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

Quiero actualizar la tabla n. ° 1 con los datos de la tabla n. ° 2 y verificar el género y la fecha de nacimiento y hacer que la tabla n. ° 1 me guste

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

¿Cómo puedo hacer esto?

John Doe
fuente
1
¿Y qué pasa si hay 2 o más personas con el mismo sexo y fecha de nacimiento? ¿Qué teléfono y dirección (de los muchos) deben copiarse?
ypercubeᵀᴹ
no es posible, esto es solo una tabla de prueba, en mis datos reales no es posible que la misma persona tenga los mismos valores.
John Doe
Si realmente no es posible, es decir, si hay una UNIQUErestricción table2 (gender, birthdate), debe agregar esa información en la pregunta.
ypercubeᵀᴹ

Respuestas:

26

Hay bastantes maneras de lograr los resultados deseados.

Métodos indeterministas

(en el caso de que muchas filas en la tabla 2 coincidan con una en la tabla 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 un poco más 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 

Métodos deterministas

MERGE arrojaría un error en lugar de aceptar resultados no deterministas

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; 

O puede elegir un registro específico si hay más de una coincidencia

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;
Martin Smith
fuente
¡Gracias por tu gran ayuda! Tengo 2 preguntas: 1) Creo que es una forma simple de hacer esto, creo que de esta manera es disminuir el rendimiento y si tengo un registro de aproximadamente 50 millones de esta manera es muy lento, ¿está de acuerdo? 2) de esta manera, si quiero unir 2table y algunas columnas en la tabla # 2 no existen en la tabla # 1, ¿recibí algún error? por ejemplo, si tengo una columna de color en la tabla n. ° 2 y no existe en la tabla n. ° 1, ¿el proceso de unión tiene un error o simplemente existen columnas de unión en 2 tablas? Gracias de nuevo ...
John Doe
1
@JohnDoe si tiene una pregunta de rendimiento, haga una nueva pregunta y proporcione detalles de los tamaños de tabla, estructuras, índices y planes de ejecución. No entiendo lo que está preguntando en el punto 2, edite su pregunta y proporcione estructuras de tabla de ejemplo que demuestren el problema que está preguntando.
Martin Smith
1
@JohnDoe: Si quiere decir columna, quiere decir un valor de columna (en otras palabras, una fila coincidente ): cuando no hay una fila coincidente, no se genera ningún error. En el caso de una unión interna (como aquí), las filas no coincidentes simplemente no se actualizarán, pero si realmente se refería a una columna que existe en una tabla y no existe en la otra, entonces creo que es una Más preguntas nuevas para hacer por separado.
Andriy M
En ese primer CTE, ¿cómo sabe SQL Server qué tabla actualizar?
RonJohn
@RonJohn Conoce la fuente de las columnas. es decir, ambos tgt_addressy tgt_phoneson alias para las columnas en #Table1, por lo que ese es el objetivo de la actualización.
Martin Smith
0
UPDATE TS
SET TS.TaskFullAddress = L.FullAddress
FROM [dbo].[TaskOrders]   TS
INNER JOIN Locations L
ON  TS.ClientId  = L.ClientId;
David Fawzy
fuente
Los nombres de campo en la respuesta no coinciden con los nombres de campo en la pregunta, pero la técnica funciona.
RonJohn
Gracias Ron, solo dando la idea
David Fawzy
Que es , sin embargo, ¿por qué su respuesta fue rechazada.
RonJohn
Gracias, no estoy seguro, ya que copié el código funcionaba en mi aplicación en vivo
David Fawzy,