748 Stimmen

Wie wählt man alle Datensätze einer Tabelle aus, die in einer anderen Tabelle nicht existieren?

table1 (id, name)
table2 (id, name)

Abfrage:

SELECT name   
FROM table2  
-- die noch nicht in table1 vorhanden sind

0 Stimmen

Schauen Sie sich die Lösung mit UNION unten an, die um ein Vielfaches schneller ist als jede andere hier aufgeführte Lösung.

1267voto

Kris Punkte 38235
SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL

Q: Was passiert hier?

A: Konzeptuell wählen wir alle Zeilen aus table1 aus und versuchen für jede Zeile eine Zeile in table2 mit dem gleichen Wert für die Spalte name zu finden. Wenn es keine solche Zeile gibt, lassen wir den table2 Teil unseres Ergebnisses einfach leer für diese Zeile. Dann begrenzen wir unsere Auswahl, indem wir nur die Zeilen im Ergebnis auswählen, in denen die entsprechende Zeile nicht existiert. Schließlich ignorieren wir alle Felder aus unserem Ergebnis außer der name Spalte (diejenige, von der wir sicher sind, dass sie existiert, aus table1).

Auch wenn es möglicherweise nicht die performanteste Methode in allen Fällen ist, sollte sie in praktisch jedem Datenbank-Engine funktionieren, das versucht, ANSI 92 SQL umzusetzen

22 Stimmen

@z-boss: Es ist auch das am wenigsten performante auf SQL Server: explainextended.com/2009/09/15/…

0 Stimmen

@Kris lass mich eine Sache klarstellen, dass du einen linken Join anwendest und table1 die linke Tabelle ist, aber du die Bedingung auf der rechten Tabelle anwendest, die Table 2 ist. Aber ich habe gelesen, dass wenn du einen linken Join anwendest, solltest du auch eine WHERE-Bedingung auf der linken Tabelle anwenden, sonst wird es wie ein innerer Join funktionieren. Könntest du mir das bitte erklären?

10 Stimmen

@BunkerBoy: Ein left join ermöglicht es, dass auf der rechten Seite Zeilen nicht vorhanden sind, ohne dass dies die Einbeziehung von Zeilen auf der linken Seite beeinflusst. Ein inner join erfordert, dass Zeilen auf der linken und der rechten Seite vorhanden sind. Was ich hier mache, ist die Anwendung einiger Logik, um im Grunde genommen die umgekehrte Auswahl eines inner joins zu erhalten.

349voto

froadie Punkte 75709

Sie können entweder tun

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT name 
     FROM table1)

oder

SELECT name 
FROM table2 
WHERE NOT EXISTS 
    (SELECT * 
     FROM table1 
     WHERE table1.name = table2.name)

Sehen Sie diese Frage für 3 Techniken, um dies zu erreichen

66 Stimmen

Dies ist mit großen Datenmengen unglaublich langsam.

1 Stimmen

Ja, in der Tat ist es sehr langsam

1 Stimmen

Sollte es nicht "von tabelle1" in der Unterabfrage der not exists Abfrage sein.

172voto

Tan Rezaei Punkte 1587

Ich habe nicht genug Bewertungspunkte, um froadies Antwort zu wählen. Aber ich muss den Kommentaren zu Kris Antwort widersprechen. Die folgende Antwort:

SELECT name
FROM table2
WHERE name NOT IN
    (SELECT name 
     FROM table1)

ist in der Praxis WESENTLICH effizienter. Ich weiß nicht warum, aber ich führe es gegenüber 800k+ Datensätzen aus und der Unterschied ist enorm zugunsten der oben genannten 2. Antwort. Nur meine 2 Cent.

50 Stimmen

Im NOT IN-Abfrage wird die Unterabfrage nur einmal ausgeführt, in der EXISTS-Abfrage wird die Unterabfrage für jede Zeile ausgeführt.

7 Stimmen

Du bist fantastisch :) Auf diese Weise habe ich meine 25-Sekunden-Abfrage mit einem Left Join auf nur 0,1 Sekunden reduziert.

6 Stimmen

Die Antworten sind nicht in einer bestimmten Reihenfolge, daher bedeutet zweite Antwort nicht das, was du dachtest.

99voto

Anuraj Punkte 2353
SELECT <column_list>
FROM TABLEA a
LEFTJOIN TABLEB b 
ON a.Key = b.Key 
WHERE b.Key IS NULL;

Bildbeschreibung hier eingeben

https://www.cloudways.com/blog/how-to-join-two-tables-mysql/

12 Stimmen

19 Stimmen

Leider sind Joint-Diagramme viel weniger klar und viel schwerer intuitiv zu verstehen als Venn-Diagramme.

2 Stimmen

Vielen Dank für die Diagramme

53voto

Winter Punkte 1458

Dies ist reine Mengenlehre, die Sie mit der minus-Operation erreichen können.

select id, name from table1
minus
select id, name from table2

1 Stimmen

Denken Sie, dass dies viel effizienter ist als ein LEFT JOIN?

4 Stimmen

Es sollte sein. Der Minus-Befehl ist genau für diese Situation konzipiert. Natürlich ist der einzige Weg, um für jeden einzelnen Datensatz eine Bewertung abzugeben, ihn auf beide Arten auszuprobieren und zu sehen, welche schneller läuft.

16 Stimmen

Im T-SQL ist der Set-Operator "except". Das ist sehr praktisch für mich und hat keine Verlangsamung verursacht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X