Per cominciare, un link ad un vecchio articolo nel mio blog su come NOT IN
predicato lavora in SQL Server
(e in altri sistemi troppo):
Puoi riscriverlo come segue:
SELECT *
FROM Orders o
WHERE NOT EXISTS
(
SELECT NULL
FROM HeldOrders ho
WHERE ho.OrderID = o.OrderID
)
, tuttavia, la maggior parte dei database tratterà queste query allo stesso modo.
Entrambe queste query useranno una specie di ANTI JOIN
.
Questo è utile per SQL Server
se si desidera controllare due o più colonne, dal momento che SQL Server
non supporta questa sintassi:
SELECT *
FROM Orders o
WHERE (col1, col2) NOT IN
(
SELECT col1, col2
FROM HeldOrders ho
)
Si noti, tuttavia, che NOT IN
può essere difficile a causa del modo in cui tratta NULL
valori.
Se Held.Orders
è annullabile, nessun record si trovano e la sottoquery non restituisce, ma un unico NULL
, tutta la query restituirà nulla (sia IN
e NOT IN
valuterà a NULL
in questo caso).
Considerare questi dati:
Orders:
OrderID
---
1
HeldOrders:
OrderID
---
2
NULL
seguente interrogazione:
SELECT *
FROM Orders o
WHERE OrderID NOT IN
(
SELECT OrderID
FROM HeldOrders ho
)
tornerà nulla, che probabilmente non è quello che ci si aspetta.
Tuttavia, questo:
SELECT *
FROM Orders o
WHERE NOT EXISTS
(
SELECT NULL
FROM HeldOrders ho
WHERE ho.OrderID = o.OrderID
)
tornerà la riga con OrderID = 1
.
noti che LEFT JOIN
soluzioni proposte da altri è lungi dall'essere una soluzione più efficiente.
interrogazione:
SELECT *
FROM Orders o
LEFT JOIN
HeldOrders ho
ON ho.OrderID = o.OrderID
WHERE ho.OrderID IS NULL
userà una condizione di filtro che dovrà valutare e filtrare tutti corrispondenza righe che possono essere Numerius
Un metodo ANTI JOIN
utilizzato sia IN
e EXISTS
sarà Basta fare in modo che un record non esista una volta per ogni riga in Orders
, quindi eliminerà prima tutti i possibili duplicati:
NESTED LOOPS ANTI JOIN
e MERGE ANTI JOIN
saranno saltare i duplicati nella valutazione HeldOrders
.
- A
HASH ANTI JOIN
eliminerà i duplicati durante la creazione della tabella hash.
Il modo migliore è provare i vari approcci e esaminare i piani di esecuzione. – pjp
Nella mia situazione SQL Server 2000, dati gli indici sulle tabelle in questione, la query "Join" era la più veloce. SELEZIONA * Dagli Ordini o LEFT JOIN HeldOrders h on o.Order_ID = h.Order_ID e h.Order_ID è nullo – Stimy