MySQL: Wählen Sie Zeilen aus einer Tabelle aus, die sich nicht in einer anderen befinden

118

Wie wähle ich alle Zeilen in einer Tabelle aus, die in einer anderen nicht angezeigt werden?

Tabelle 1:

+-----------+----------+------------+
| FirstName | LastName | BirthDate  |
+-----------+----------+------------+
| Tia       | Carrera  | 1975-09-18 |
| Nikki     | Taylor   | 1972-03-04 |
| Yamila    | Diaz     | 1972-03-04 |
+-----------+----------+------------+

Tabelle 2:

+-----------+----------+------------+
| FirstName | LastName | BirthDate  |
+-----------+----------+------------+
| Tia       | Carrera  | 1975-09-18 |
| Nikki     | Taylor   | 1972-03-04 |
+-----------+----------+------------+

Beispielausgabe für Zeilen in Tabelle1, die nicht in Tabelle2 enthalten sind:

+-----------+----------+------------+
| FirstName | LastName | BirthDate  |
+-----------+----------+------------+
| Yamila    | Diaz     | 1972-03-04 |
+-----------+----------+------------+

Vielleicht sollte so etwas funktionieren:

SELECT * FROM Table1 WHERE * NOT IN (SELECT * FROM Table2)
Christopher Rapcewicz
quelle

Antworten:

96

Wenn Sie 300 Spalten haben, wie Sie in einem anderen Kommentar erwähnt haben, und alle Spalten vergleichen möchten (vorausgesetzt, die Spalten haben alle den gleichen Namen), können Sie mit a NATURAL LEFT JOINimplizit alle übereinstimmenden Spaltennamen zwischen den beiden Tabellen verknüpfen, sodass Sie Sie müssen nicht mühsam alle Verknüpfungsbedingungen manuell eingeben:

SELECT            a.*
FROM              tbl_1 a
NATURAL LEFT JOIN tbl_2 b
WHERE             b.FirstName IS NULL
Zane Bien
quelle
Beachten Sie, dass dies nur wie erwartet funktioniert, wenn keine der Spalten NULL-Werte hat. In MySQL ist NULL! = NULL, sodass jede Zeile mit einem NULL-Wert zurückgegeben wird, auch wenn die zweite Tabelle eine doppelte Zeile enthält.
Kyle Kochis
84
Wenn Sie 300 Spalten haben, sollten Sie Ihre Datenbank neu gestalten.
Iharob Al Asimi
Hey, das funktioniert auch bei mir, danke! Aber wäre das ein Problem, wenn die Zeilen> 300 sind, wie Sie oben erwähnt haben?
Thekucays
Ich bin immer noch verwirrt über die Abfrage übrigens ... was ist, wenn ich zum Beispiel "wo b.FirstName null ist" in "wo b.LastName null ist" ändere? was ist der Unterschied? Es tut mir leid, dass ich das gefragt habe. Ich bin noch neu in SQL: D
Thekucays
184

Sie müssen die Unterauswahl basierend auf einem Spaltennamen durchführen, nicht *.

Wenn Sie beispielsweise ein idFeld haben, das beiden Tabellen gemeinsam ist, können Sie Folgendes tun:

SELECT * FROM Table1 WHERE id NOT IN (SELECT id FROM Table2)

Weitere Beispiele finden Sie in der MySQL-Unterabfragesyntax .

Stennie
quelle
1
Danke für die Klarstellung! Aber ich muss die Auswahl der Zeilen wirklich nicht auf ein Feld stützen, da ich an einer Variation eines Feldes in der Zeile interessiert bin ...
Wenn nur wenige Spalten zum Vergleichen vorhanden sind, können Sie einen Join gemäß dem Beispiel von @ Steve durchführen. Wenn Sie tatsächlich nach einem allgemeinen Vergleich von Daten in zwei Tabellen mit vielen Spalten fragen, möchten Sie wahrscheinlich nach einem MySQL-Diff-Tool suchen .
Stennie
2
Beachten Sie, dass dies immer eine leere Menge zurückgibt, wenn die Spalte, die Sie in Tabelle 2 betrachten, Nullen enthält. Kein Problem, wenn Sie es basierend auf dem Primärschlüssel tun, aber relevant für Leute, die versuchen, diese Abfrage in anderen Kontexten zu verwenden.
Mark Amery
4
Aber was ist, wenn wir über Big Data sprechen? Und Tabelle2 enthält zum Beispiel 100 Millionen Zeilen?
Frops
Kluge und kluge Antwort. Danke Kumpel
Anjana Silva
44
SELECT *
FROM Table1 AS a
WHERE NOT EXISTS (
  SELECT *
  FROM Table2 AS b 
  WHERE a.FirstName=b.FirstName AND a.LastName=b.Last_Name
)

EXISTS wird dir helfen...

Ruzbeh Irani
quelle
2
Gute Antwort, wirtschaftlich für große Datenmengen, danke.
ekerner
Stark. Beste Antwort für große Datenmengen
Ian Chadwick
35

Ein Standard-LEFT JOIN könnte das Problem lösen und sollte auch schneller sein , wenn die Felder beim Join indiziert sind

SELECT *
FROM Table1 as t1 LEFT JOIN Table2 as t2 
ON t1.FirstName = t2.FirstName AND t1.LastName=t2.LastName
WHERE t2.BirthDate Is Null
Steve
quelle
in Ordnung, ich denke das muss es sein, übrigens warum das WHERE t2.Birthdate Is Nullstatt AND t1.Birthdate = t2.Birthdate?
Denn wenn Sie das hinzufügen, wird jede Zeile zurückgegeben, Sie sagen, dass in der Ausgabe nur Zeilen erscheinen sollten, die nicht in der zweiten Tabelle enthalten sind
Steve
1
Dies ist eine großartige Antwort, da nicht alle Zeilen von zurückgegeben werden müssen Table2!
Dotancohen
Ich stimme zu, tolle Antwort. Ich habe einen Mann-viele-Tisch zwischen 4 Tischen, das UND in den inneren Join zu setzen, wird definitiv wirtschaftlicher sein.
DR.
6

Versuchen:

SELECT * FROM table1
    LEFT OUTER JOIN table2
    ON table1.FirstName = table2.FirstName and table1.LastName=table2.LastName
    WHERE table2.BirthDate IS NULL
Sachin Pundir
quelle
4

Versuchen Sie diese einfache Abfrage. Es funktioniert perfekt.

select * from Table1 where (FirstName,LastName,BirthDate) not in (select * from Table2);
Vijesh
quelle
-3

Dies hat bei mir in Oracle funktioniert:

SELECT a.* 
    FROM tbl1 a 
MINUS 
SELECT b.* 
    FROM tbl2 b;
Gennady Sorochan
quelle
Die Frage betraf MySQL.
Jelder
-6
SELECT a.* FROM 
FROM tbl_1 a
MINUS
SELECT b.* FROM 
FROM tbl_2 b
Ingrid R. Forsale
quelle