Perbarui tabel menggunakan nilai dari tabel lain di SQL Server

13

Saya memiliki 2 tabel di database saya.

Tabel 1

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

Meja 2

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

pada tabel # 1 kolom alamat dan phone2 kosong dan kolom gender dan tanggal lahir sama dengan tabel # 2.

Bagaimana saya bisa membaca data dari tabel # 2 dan memperbarui alamat dan phone2 dalam tabel # 1 dengan nilai dari tabel # 2 alamat dan kolom telepon ketika jenis kelamin dan tanggal lahir sama di setiap baris?

misalnya: ini adalah beberapa data dalam Tabel # 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|
-------------------------------------------------------------------------

dan berikut adalah beberapa data dalam tabel # 2

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

Saya ingin memperbarui tabel # 1 dengan data dari tabel # 2 dan memeriksa jenis kelamin dan tanggal lahir dan membuat tabel # 1 seperti

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

Bagaimana saya bisa melakukan ini?

John Doe
sumber
1
Dan bagaimana jika ada 2 orang atau lebih dengan jenis kelamin dan tanggal lahir yang sama? Telepon dan alamat mana (dari banyak) yang harus disalin?
ypercubeᵀᴹ
ini tidak mungkin, ini hanya tabel uji, dalam data saya yang sebenarnya tidak mungkin untuk orang yang sama memiliki nilai yang sama.
John Doe
Jika itu benar-benar tidak mungkin, yaitu jika ada UNIQUEkendala pada table2 (gender, birthdate), Anda harus menambahkan info itu dalam pertanyaan.
ypercubeᵀᴹ

Jawaban:

26

Ada beberapa cara untuk mencapai hasil yang Anda inginkan.

Metode yang tidak ditentukan

(dalam hal banyak baris dalam tabel 2 cocok satu dalam tabel 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

Atau bentuk yang sedikit lebih ringkas

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

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

Metode deterministik

MERGE akan melempar kesalahan daripada menerima hasil non deterministik

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; 

Atau Anda dapat memilih catatan tertentu jika ada lebih dari satu pertandingan

Dengan 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 

.. Atau 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
sumber
Terima kasih atas bantuan Anda! Saya punya 2 pertanyaan: 1) Saya pikir ini cara mudah untuk melakukan ini, saya pikir cara ini menurunkan kinerja dan jika saya memiliki sekitar 50 juta catatan cara ini sangat lambat, apakah Anda setuju? 2) dengan cara ini, jika saya ingin bergabung dengan 2table dan beberapa kolom pada tabel # 2 tidak ada pada tabel # 1 saya mendapat kesalahan? misalnya jika saya memiliki kolom warna pada tabel # 2 dan tidak ada pada tabel # 1, bergabung dengan proses mendapat kesalahan atau hanya bergabung dengan kolom ada di 2tabel? Terima kasih lagi ...
John Doe
1
@ JohnDoe jika Anda memiliki pertanyaan kinerja, tanyakan pertanyaan baru dan berikan rincian ukuran tabel, struktur, indeks, dan rencana eksekusi. Saya tidak mengerti apa yang Anda tanyakan pada poin 2, harap edit pertanyaan Anda dan berikan struktur tabel contoh yang menunjukkan masalah yang Anda tanyakan.
Martin Smith
1
@ JohnDoe: Jika Anda maksud dengan kolom yang Anda maksud adalah nilai kolom (dengan kata lain, baris yang cocok ) - ketika tidak ada baris yang cocok, tidak ada kesalahan yang muncul. Dalam kasus gabungan dalam (seperti di sini), baris yang tidak cocok tidak akan diperbarui. Tetapi jika Anda memang berarti kolom yang ada di satu tabel dan tidak ada di yang lain, maka saya percaya itu adalah satu lebih banyak pertanyaan baru untuk ditanyakan secara terpisah.
Andriy M
Pada CTE pertama itu, bagaimana SQL Server tahu tabel apa yang harus diperbarui?
RonJohn
@ RonJohn Ia tahu sumber kolom. yaitu bahwa keduanya tgt_addressdan tgt_phonealias untuk kolom di #Table1- sehingga merupakan target untuk pembaruan.
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
sumber
Nama bidang dalam jawaban tidak cocok dengan nama bidang dalam pertanyaan, tetapi teknik ini berfungsi.
RonJohn
Terima kasih Ron, hanya memberikan ide
David Fawzy
Ini adalah , meskipun, mengapa jawaban Anda itu ditolak.
RonJohn
Terima kasih tidak yakin, karena saya menyalin kode bekerja di aplikasi langsung saya
David Fawzy