Aktualisieren Sie die Tabelle mit Werten aus einer anderen Tabelle in SQL Server


11

Ich habe 2 Tabellen in meiner Datenbank.

Tabelle 1

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

Tabelle 2

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

In Tabelle 1 sind die Spalten Adresse und Telefon2 leer und die Spalten Geschlecht und Geburtsdatum entsprechen denen in Tabelle 2.

Wie kann ich Daten aus Tabelle 2 lesen und Adresse und Telefon 2 in Tabelle 1 mit Werten aus Tabelle 2 Adresse und Telefonspalten aktualisieren, wenn Geschlecht und Geburtsdatum in jeder Zeile gleich sind?

Beispiel: Dies sind einige Daten in Tabelle 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|
-------------------------------------------------------------------------

und hier sind einige Daten in Tabelle 2

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

Ich möchte Tabelle 1 mit Daten aus Tabelle 2 aktualisieren und Geschlecht und Geburtsdatum überprüfen und Tabelle 1 mögen

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

Wie kann ich das machen?


1
Und was ist, wenn es zwei oder mehr Personen mit gleichem Geschlecht und Geburtsdatum gibt? Welches Telefon und welche Adresse (von den vielen) soll kopiert werden?
Ypercubeᵀᴹ

Es ist nicht möglich, dies ist nur eine Testtabelle. In meinen realen Daten ist es nicht möglich, dass dieselbe Person dieselben Werte hat.
John Doe

Wenn es wirklich nicht möglich ist, dh wenn es eine UNIQUEEinschränkung gibt table2 (gender, birthdate), sollten Sie diese Informationen in die Frage einfügen.
Ypercubeᵀᴹ

Antworten:


24

Es gibt viele Möglichkeiten, um die gewünschten Ergebnisse zu erzielen.

Undeterministische Methoden

(für den Fall, dass viele Zeilen in Tabelle 2 mit einer in Tabelle 1 übereinstimmen)

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

Oder eine etwas prägnantere Form

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

Oder mit einem 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 

Deterministische Methoden

MERGE würde einen Fehler auslösen, anstatt nicht deterministische Ergebnisse zu akzeptieren

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; 

Oder Sie können einen bestimmten Datensatz auswählen, wenn mehr als eine Übereinstimmung vorliegt

Mit 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 

.. Oder ein 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;

Vielen Dank für Ihre Hilfe! Ich habe 2 Fragen: 1) Ich denke, es ist ein einfacher Weg, dies zu tun. Ich denke, dieser Weg verringert die Leistung. Wenn ich ungefähr 50 Millionen Aufzeichnungen habe, ist dieser Weg sehr langsam. Stimmen Sie zu? 2) Wenn ich auf diese Weise Join 2table möchte und einige Spalten in Tabelle 2 nicht in Tabelle 1 vorhanden sind, habe ich einen Fehler erhalten? Wenn ich beispielsweise eine Farbspalte in Tabelle 2 habe und diese in Tabelle 1 nicht vorhanden ist, hat der Verknüpfungsprozess einen Fehler erhalten oder sind nur Verknüpfungsspalten in 2 Tabellen vorhanden?
John Doe

1
@JohnDoe Wenn Sie eine Leistungsfrage haben, stellen Sie eine neue Frage und geben Sie Details zu Tabellengrößen, Strukturen, Indizes und Ausführungsplänen an. Ich verstehe nicht, was Sie in Punkt 2 fragen. Bitte bearbeiten Sie Ihre Frage und geben Sie Beispieltabellenstrukturen an, die das Problem veranschaulichen, zu dem Sie fragen.
Martin Smith

1
@JohnDoe: Wenn Sie mit dem Spalte bedeuten Sie eine Spalte bedeuten Wert (in anderen Worten, eine passende Zeile ) - wenn es keine passende Zeile ist, wird kein Fehler ausgelöst. Im Falle eines inneren Joins (wie hier) werden die nicht übereinstimmenden Zeilen einfach nicht aktualisiert. Wenn Sie jedoch tatsächlich eine Spalte gemeint haben , die in einer Tabelle vorhanden ist und in der anderen nicht vorhanden ist, dann glaube ich, dass dies eine ist Weitere neue Fragen separat zu stellen.
Andriy M

Woher weiß SQL Server auf diesem ersten CTE, welche Tabelle aktualisiert werden muss?
RonJohn

@ RonJohn Es kennt die Quelle der Spalten. dh dass beide tgt_addressund tgt_phoneAliase für Spalten in sind #Table1- das ist also das Ziel für das Update.
Martin Smith

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

Die Feldnamen in der Antwort stimmen nicht mit den Feldnamen in der Frage überein, aber die Technik funktioniert.
RonJohn

Danke Ron, ich gebe nur die Idee
David Fawzy

Es ist jedoch der Grund, warum Ihre Antwort abgelehnt wurde.
RonJohn

Vielen Dank nicht sicher, da ich Code kopiert funktionierte in meiner Live-Anwendung
David Fawzy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.