2016-06-01 2 views
0

Ich habe zwei identische Tabellen von verschiedenen Servern. Als kurze Lösung (um einen längeren Fix zu bewältigen, da es sich um VERY-Infrastruktur handelt) zur Identifizierung doppelter PKs haben wir beschlossen, in der ersten Phase eine Liste von Datensätzen zu erstellen, deren Primärschlüssel in der anderen Datenbank vorhanden ist ist identisch. Selbst wenn sie die gleichen PK hätten, hätten sie immer noch andere Daten im Rest des Tupels (oder des Eintrags) wie Vorname, Nachname, usw.UNION-Anweisung funktioniert nicht, gezwungen, JOIN zu verwenden (Leistungsdominanz durch entweder?)

Ich versuche diese UNION-Anweisung seit sie zu verwenden sind beide identisch Tabellen, aber halten Sie Fehler als zu „Unbekannte Spalten in dem‚Wo‘-Klausel“

SELECT T.`hospitalno` AS HospitalnoMain, T.`dateencoded` AS DateEncodedMain, 
    T.`firstname` AS FirstNameMain, T.`lastname` AS LastNameMain 
FROM registration.`patmaster` T 
UNION 
SELECT P.`hospitalno` AS HospitalnoAux, P.`dateencoded` AS DateEncodedAux, 
    P.`firstname` AS FirstNameAux, P.`lastname` AS LastNameAux 
FROM registration.`patmaster` P 
WHERE T.`LastNameMain` <> P.`LastNameAux` AND T.`FirstNameMain` <> P.`FirstNameAux` 
LIMIT 100 

so siedelt ich habe für diese Aussage, dass die richtigen Daten ziehen (zumindest durch alle Anpassungen immer zu Datensätze, um die Abfrage zu testen, ist es richtig).

SELECT * FROM 
(
    SELECT T.`hospitalno` AS HospitalnoMain, T.`dateencoded` AS DateEncodedMain, 
     T.`firstname` AS FirstNameMain, T.`lastname` AS LastNameMain 
    FROM registration.`patmaster` t 
) AS G 
LEFT OUTER JOIN 
(
    SELECT P.`hospitalno` AS HospitalnoAux, P.`dateencoded` AS DateEncodedAux, 
     P.`firstname` AS FirstNameAux, P.`lastname` AS LastNameAux 
    FROM registration.`patmaster` p 
) H 
    ON G.HospitalnoMain = H.HospitalnoAux 
WHERE G.`LastNameMain` <> H.`LastNameAux` AND G.`FirstNameMain` <> H.`FirstNameAux` 
LIMIT 100 

- bitte die manuelle Eingabe Format entschuldigen.

Meine Frage ist, die Leistung ist besser, da es große Datenmengen durch beide Tabellen ziehen wird. und wenn es UNION ist, was ist falsch mit meiner UNION-Anweisung, da ich Variationen der SELECT-Anweisung ausprobiert habe, die mir den gleichen "unbekannte Spalte ..." -Fehler geben. Vielen Dank im Voraus

EDIT auch, wenn jemand weiß, wie man SQL in "Code" verwendet, würde ich es zu schätzen wissen. Es scheint nicht zu funktionieren hier

+0

Ich denke, Sie missverstanden 'UNION' Verwendung – Fabricator

+0

Ich glaube, Ihre UNION ist wegen Ihrer WHERE-Klausel fehlgeschlagen. Damit es funktioniert, sollte jede Abfrage für sich stehen und die gleichen Spaltennamen zurückgeben (ich glaube in der gleichen Reihenfolge, aber ich bin nicht davon überzeugt). Stellen Sie sich den Motor so vor, als ob Sie ein Ergebnis übereinander stapeln würden. Ihre WHERE-Klausel schlägt fehl, weil sie in der zweiten Abfrage nach einer Tabelle T sucht, in der zweiten Abfrage jedoch keine Tabelle T vorhanden ist. Sobald Sie es zum Laufen gebracht haben, glaube ich, dass Sie eine UNION ALL anstatt nur einer UNION verwenden möchten (ohne die ALL, die doppelten Zeilen, die Sie versuchen zu finden, werden jeweils zu einer Zeile zusammengefasst) – Ben

+0

Diese Abfragen kehren zurück verschiedene Dinge. Sie haben uns nicht gesagt, welche Zeilen die Abfrage zurückgeben soll. Und Sie haben uns nicht gesagt, welches (möglicherweise dritte) Abfrageergebnis tatsächlich ist, was Sie brauchen. – philipxy

Antwort

2

Ihre left join ist in Ordnung. . . vorausgesetzt, es macht was du willst. Verwenden Sie keine Unterabfragen in der from-Klausel, wenn sie nicht benötigt werden. MySQL materialisiert solche Unterabfragen, wodurch zusätzlicher Overhead entsteht.

SELECT T.`hospitalno` AS HospitalnoMain, T.`dateencoded` AS DateEncodedMain, 
     P.`hospitalno` AS HospitalnoAux, P.`dateencoded` AS DateEncodedAux, P.`firstname` AS FirstNameAux, P.`lastname` AS LastNameAux 
FROM registration.`patmaster` t INNER JOIN 
    registration.`patmaster` p 
    ON p.hospitalno = t.hospitalno 
WHERE t.`LastNameMain` <> p.`LastName` AND t.`FirstNameMain` <> p.`FirstName` 
LIMIT 100; 

Hinweis: Die where Klausel schaltet sich der äußere Verknüpfung in eine innere Verknüpfung sowieso, so gibt es Grund, warum es eine Außen zu machen verbinden.

1

Beachten Sie, dass diese Abfrage (wie das Original) doppelte Kopien der Zeilen ziehen wird, eine Zeile mit den Werten "Main" und "Aux" umgekehrt. Im allgemeineren Fall, wo die Möglichkeit besteht, dass Vor- oder Nachname NULL sein könnte, können wir einen Null-sicheren Vergleich <=> (Raumschiff) -Operator verwenden, so dass der Vergleich nur TRUE oder FALSE liefert und kein a zurückgibt NULL.

SELECT t.`hospitalno` AS HospitalnoMain 
    , t.`dateencoded` AS DateEncodedMain 
    , t.`firstname`  AS FirstNameMain 
    , t.`lastname`  AS LastNameMain 
    , p.`hospitalno` AS HospitalnoAux 
    , p.`dateencoded` AS DateEncodedAux 
    , p.`firstname`  AS FirstNameAux 
    , p.`lastname`  AS LastNameAux 
FROM registration.`patmaster` t 
LEFT 
JOIN registration.`patmaster` p 
    ON p.hospitalno = t.hospitalno 
     AND NOT (t.firstname <=> p.firstname) 
     AND NOT (t.lastname <=> p.lastname ) 
Verwandte Themen