Cập nhật bảng bằng các giá trị từ một bảng khác trong SQL Server


11

Tôi có 2 bảng trong cơ sở dữ liệu của mình.

Bảng 1

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

Ban 2

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

trong bảng số 1 địa chỉ cột và phone2 trống và các cột giá trị giới tínhngày sinh giống như bảng số 2.

Làm cách nào tôi có thể đọc dữ liệu từ bảng số 2 và cập nhật địa chỉphone2 trong bảng số 1 với các giá trị từ địa chỉ bảng số 2 và các cột điện thoại khi giới tínhngày sinh giống nhau ở mỗi hàng?

ví dụ: đây là một số dữ liệu trong Bảng # 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|
-------------------------------------------------------------------------

và đây là một số dữ liệu trong bảng # 2

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

Tôi muốn cập nhật bảng số 1 với dữ liệu từ bảng số 2 và kiểm tra giới tínhngày sinh và tạo bảng số 1 như

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

Tôi có thể làm cái này như thế nào?


1
Và nếu có từ 2 người trở lên có cùng giới tính và ngày sinh thì sao? Những điện thoại và địa chỉ (trong số nhiều) nên được sao chép?
ypercubeᵀᴹ

Không thể, đây chỉ là bảng thử nghiệm, trong dữ liệu thực của tôi, không thể cùng một người có cùng giá trị.
John Doe

Nếu nó thực sự không thể, tức là nếu có một UNIQUEràng buộc nào đó table2 (gender, birthdate), bạn nên thêm thông tin đó vào câu hỏi.
ypercubeᵀᴹ

Câu trả lời:


24

Có khá nhiều cách để đạt được kết quả mong muốn của bạn.

Phương pháp không xác định

(trong trường hợp nhiều hàng trong bảng 2 khớp với một trong bảng 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

Hoặc một hình thức ngắn gọn hơn một chút

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

Hoặc với 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 

Phương pháp xác định

MERGE sẽ đưa ra một lỗi thay vì chấp nhận kết quả không xác định

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; 

Hoặc bạn có thể chọn một bản ghi cụ thể nếu có nhiều hơn một trận đấu

Với 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 

.. Hoặc 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;

Cảm ơn vì sự giúp đỡ tuyệt vời của bạn! Tôi có 2 câu hỏi: 1) Tôi nghĩ rằng đó là cách đơn giản để làm điều này, tôi nghĩ cách này là giảm hiệu suất và nếu tôi có khoảng 50m Record thì cách này rất chậm, bạn có đồng ý không? 2) theo cách này, nếu tôi muốn tham gia 2table và một số cột trong bảng # 2 không tồn tại trong bảng # 1 tôi có lỗi gì không? ví dụ: nếu tôi có cột màu trong bảng số 2 và nó không tồn tại trên bảng số 1, quá trình nối có bị lỗi hoặc chỉ tham gia các cột tồn tại trong 2tables? Cảm ơn một lần nữa ...
John Doe

1
@JohnDoe nếu bạn có một câu hỏi về hiệu năng, hãy hỏi một câu hỏi mới và cung cấp chi tiết về kích thước bảng, cấu trúc, chỉ mục và kế hoạch thực hiện. Tôi không hiểu những gì bạn đang hỏi ở điểm 2, vui lòng chỉnh sửa câu hỏi của bạn và cung cấp các cấu trúc bảng ví dụ thể hiện vấn đề bạn đang hỏi về.
Martin Smith

1
@JohnDoe: Nếu bạn có nghĩa là theo cột, bạn có nghĩa là một giá trị cột (nói cách khác, một hàng khớp ) - khi không có hàng phù hợp, không có lỗi nào được đưa ra. Trong trường hợp tham gia bên trong (như ở đây), (các) hàng chưa từng có sẽ không được cập nhật. Nhưng nếu bạn thực sự có nghĩa là một cột tồn tại trong một bảng và không tồn tại trong một bảng khác, thì tôi tin đó là một hàng thêm câu hỏi mới để hỏi riêng.
Andriy M

Trên CTE đầu tiên đó, SQL Server biết bảng nào cần cập nhật?
RonJohn

@RonJohn Nó biết nguồn của các cột. tức là cả hai tgt_addresstgt_phonelà bí danh cho các cột trong #Table1- vì vậy đó là mục tiêu cho bản cập nhật.
Martin Smith

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

Tên trường trong câu trả lời không khớp với tên trường trong câu hỏi, nhưng kỹ thuật hoạt động.
RonJohn

Cảm ơn Ron, chỉ đưa ra ý tưởng
David Fawzy

Đó , mặc dù, tại sao câu trả lời của bạn đã được bỏ phiếu xuống.
RonJohn

Cảm ơn không chắc chắn, vì tôi đã sao chép mã đang hoạt động trong ứng dụng trực tiếp của mình
David Fawzy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.