Grundsätzlich gibt es 4 Techniken für diese Aufgabe, allesamt Standard-SQL.
NOT EXISTS
Oft am schnellsten in Postgres.
SELECT ip
FROM login_log l
WHERE NOT EXISTS (
SELECT -- SELECT list mostly irrelevant; can just be empty in Postgres
FROM ip_location
WHERE ip = l.ip
);
Beachten Sie auch:
- Was ist in EXISTS-Unterabfragen einfacher zu lesen?
LEFT JOIN / IS NULL
Manchmal geht das am schnellsten. Oft am kürzesten. Führt oft zu demselben Abfrageplan wie NOT EXISTS
.
SELECT l.ip
FROM login_log l
LEFT JOIN ip_location i USING (ip) -- short for: ON i.ip = l.ip
WHERE i.ip IS NULL;
EXCEPT
Kurz. Nicht so einfach in komplexere Abfragen integrierbar.
SELECT ip
FROM login_log
EXCEPT ALL -- "ALL" keeps duplicates and makes it faster
SELECT ip
FROM ip_location;
Beachten Sie, dass (laut Dokumentation):
Duplikate werden eliminiert, es sei denn EXCEPT ALL
verwendet wird.
Normalerweise möchten Sie ALL
Stichwort. Wenn es Ihnen egal ist, verwenden Sie es trotzdem, da es die Abfrage schneller macht .
NOT IN
Nur gut ohne NULL
Werte oder wenn Sie wissen, wie man mit NULL
umgeht richtig. Ich würde nicht verwenden Sie es für diesen Zweck. Außerdem kann sich die Leistung bei größeren Tabellen verschlechtern.
SELECT ip
FROM login_log
WHERE ip NOT IN (
SELECT DISTINCT ip -- DISTINCT is optional
FROM ip_location
);
NOT IN
trägt eine "Falle" für NULL
Werte auf beiden Seiten:
- Suchen Sie Datensätze, in denen keine Verknüpfung vorhanden ist
Ähnliche Frage zu dba.SE für MySQL:
- Wählen Sie Zeilen aus, in denen der Wert der zweiten Spalte nicht in der ersten Spalte vorhanden ist