Für den Anfang, ein Link zu einem alten Artikel in meinem Blog darüber, wie NOT IN
Prädikat arbeitet in SQL Server
(und in anderen Systemen auch):
Sie können es wie folgt umschreiben:
SELECT *
FROM Orders o
WHERE NOT EXISTS
(
SELECT NULL
FROM HeldOrders ho
WHERE ho.OrderID = o.OrderID
)
jedoch behandeln die meisten Datenbanken diese Abfragen gleich. Diese beiden Abfragen verwenden eine Art von ANTI JOIN
.
Dies ist nützlich für SQL Server
, wenn Sie zwei oder mehr Spalten überprüfen möchten, da SQL Server
diese Syntax nicht unterstützt:
SELECT *
FROM Orders o
WHERE (col1, col2) NOT IN
(
SELECT col1, col2
FROM HeldOrders ho
)
Beachten Sie jedoch, dass NOT IN
schwierig sein kann auf die Art und Weise da es NULL
behandelt Werte.
Wenn Held.Orders
NULL-Werte zulässt, werden keine Datensätze gefunden und die Unterabfrage gibt nur eine einzige NULL
, wird die ganze Abfrage zurückgeben nichts (beide IN
und NOT IN
wird NULL
in diesem Fall bewerten).
Betrachten Sie diese Daten:
Orders:
OrderID
---
1
HeldOrders:
OrderID
---
2
NULL
Diese Abfrage:
SELECT *
FROM Orders o
WHERE OrderID NOT IN
(
SELECT OrderID
FROM HeldOrders ho
)
kehrt nichts, das ist wahrscheinlich nicht das, was man erwarten würde.
jedoch diese:
SELECT *
FROM Orders o
WHERE NOT EXISTS
(
SELECT NULL
FROM HeldOrders ho
WHERE ho.OrderID = o.OrderID
)
wird die Zeile mit OrderID = 1
zurück.
Beachten Sie, dass LEFT JOIN
von anderen vorgeschlagene Lösungen bei weitem nicht die effizienteste Lösung ist.
Diese Abfrage:
SELECT *
FROM Orders o
LEFT JOIN
HeldOrders ho
ON ho.OrderID = o.OrderID
WHERE ho.OrderID IS NULL
wird eine Filterbedingung verwenden, die alle passende Zeilen müssen auszuwerten und auszufiltern, die
Ein ANTI JOIN
Verfahren verwendet sowohl IN
und EXISTS
Numerius werden kann, muss nur sicherstellen, dass ein Datensatz nicht existiert einmal pro Zeile in Orders
, so wird es zuerst alle möglichen Dubletten zu beseitigen:
NESTED LOOPS ANTI JOIN
und MERGE ANTI JOIN
wird nur die Duplikate überspringen, wenn HeldOrders
Auswertung.
- Ein
HASH ANTI JOIN
wird Dubletten beim Erstellen der Hash-Tabelle beseitigen.
Der beste Weg ist es, die verschiedenen Ansätze zu versuchen und die Ausführungspläne zu untersuchen. – pjp
In meiner Situation SQL Server 2000, angesichts der Indizes für die fraglichen Tabellen war die "Join" -Abfrage die schnellste. SELECT * FROM Bestellungen o LEFT JOIN HeldOrder h on o.Order_ID = h.Order_ID und h.Order_ID ist null – Stimy