Обновите таблицу, используя значения из другой таблицы в SQL Server


13

У меня есть 2 таблицы в моей базе данных.

Таблица 1

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

Таблица 2

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

в столбцах таблицы № 1 адрес и phone2 не заполнены, а значения столбцов пола и дня рождения такие же, как в таблице № 2.

Как я могу прочитать данные из таблицы № 2 и обновить адрес и номер телефона 2 в таблице № 1 значениями из столбца адреса и телефона таблицы № 2, если пол и дата рождения одинаковы в каждой строке?

например: это некоторые данные в таблице № 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|
-------------------------------------------------------------------------

и вот некоторые данные в таблице № 2

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

Я хочу обновить таблицу № 1 данными из таблицы № 2, проверить пол и дату рождения и сделать таблицу № 1 похожей

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

Как я могу это сделать?


1
А что, если есть 2 или более людей с одинаковым полом и датой рождения? Какой телефон и адрес (из многих) следует скопировать?
ypercubeᵀᴹ

это невозможно, это просто тестовая таблица, в моих реальных данных невозможно, чтобы один и тот же человек имел одинаковые значения.
Джон Доу

Если это действительно невозможно, то есть если есть UNIQUEограничение table2 (gender, birthdate), вы должны добавить эту информацию в вопрос.
ypercubeᵀᴹ

Ответы:


26

Есть немало способов достичь желаемых результатов.

Недетерминированные методы

(если много строк в таблице 2 совпадают с одной строкой в ​​таблице 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

Или немного более краткая форма

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

Или с 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 

Детерминированные методы

MERGE будет выдавать ошибку, а не принимать недетерминированные результаты

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; 

Или вы можете выбрать конкретную запись, если есть более одного совпадения

С 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 

.. или 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;

Спасибо за вашу большую помощь! У меня есть 2 вопроса: 1) Я думаю, что это простой способ сделать это, я думаю, что это снижение производительности, и если у меня около 50 миллионов записей, этот путь очень медленный, вы согласны? 2) таким образом, если я хочу соединить 2table и некоторые столбцы в таблице № 2 не существуют в таблице № 1, я получил какую-либо ошибку? например, если у меня есть цветной столбец в таблице № 2 и его нет в таблице № 1, процесс соединения получил ошибку или просто столбцы соединения существуют в 2 таблицах? Еще раз спасибо ...
Джон Доу

1
@JohnDoe, если у вас есть вопрос производительности, задайте новый вопрос и предоставьте подробную информацию о размерах таблиц, структурах, индексах и планах выполнения. Я не понимаю, что вы спрашиваете в пункте 2, пожалуйста, отредактируйте ваш вопрос и приведите примеры структур таблиц, которые демонстрируют проблему, о которой вы спрашиваете.
Мартин Смит

1
@JohnDoe: Если вы имеете в виду под столбцом, вы имеете в виду значение столбца (другими словами, совпадающую строку ) - когда нет подходящей строки, ошибка не возникает. В случае внутреннего соединения (как здесь), несопоставленные строки просто не будут обновлены. Но если вы действительно имели в виду столбец, который существует в одной таблице и не существует в другой, то я считаю, что это один Еще новый вопрос задать отдельно.
Андрей М

На том первом CTE, как SQL Server узнает, какую таблицу обновлять?
RonJohn

@RonJohn Он знает источник столбцов. то есть оба tgt_addressи tgt_phoneявляются псевдонимами для столбцов в #Table1- так что это цель для обновления.
Мартин Смит

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

Имена полей в ответе не совпадают с именами полей в вопросе, но техника работает.
RonJohn

Спасибо, Рон, просто
высказал

Это есть , хотя, почему ваш ответ был отвергнут.
RonJohn

Спасибо, не уверен, так как я скопировал код, который работал в моем живом приложении
David Fawzy
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.