Đối với người mới bắt đầu, một liên kết đến một bài báo cũ trong blog của tôi về cách NOT IN
vị làm việc trong SQL Server
(và trong các hệ thống khác nữa):
Bạn có thể viết lại như sau:
Tuy nhiên,
, hầu hết các cơ sở dữ liệu sẽ xử lý các truy vấn này giống nhau.
Cả hai truy vấn này sẽ sử dụng một số loại ANTI JOIN
.
này rất hữu ích cho SQL Server
nếu bạn muốn kiểm tra hai hoặc nhiều cột, vì SQL Server
không hỗ trợ cú pháp sau:
SELECT *
FROM Orders o
WHERE (col1, col2) NOT IN
(
SELECT col1, col2
FROM HeldOrders ho
)
Lưu ý, tuy nhiên, NOT IN
có thể được khôn lanh do cách nó đối xử với NULL
giá trị.
Nếu Held.Orders
là nullable, không có hồ sơ được tìm thấy và trở về subquery nhưng một đơn NULL
, toàn bộ truy vấn sẽ trả gì (cả IN
và NOT IN
sẽ đánh giá để NULL
trong trường hợp này).
Hãy xem xét những dữ liệu này:
Orders:
OrderID
---
1
HeldOrders:
OrderID
---
2
NULL
truy vấn này:
SELECT *
FROM Orders o
WHERE OrderID NOT IN
(
SELECT OrderID
FROM HeldOrders ho
)
sẽ trở lại gì, mà có lẽ không phải là điều bạn mong muốn.
Tuy nhiên, chương trình này:
SELECT *
FROM Orders o
WHERE NOT EXISTS
(
SELECT NULL
FROM HeldOrders ho
WHERE ho.OrderID = o.OrderID
)
sẽ trả lại hàng với OrderID = 1
.
Lưu ý rằng LEFT JOIN
giải pháp được đề xuất bởi những người khác không phải là giải pháp hiệu quả nhất.
truy vấn này:
SELECT *
FROM Orders o
LEFT JOIN
HeldOrders ho
ON ho.OrderID = o.OrderID
WHERE ho.OrderID IS NULL
sẽ sử dụng một điều kiện lọc sẽ cần phải đánh giá và lọc ra tất cả phù hợp với hàng có thể được numerius
Một ANTI JOIN
phương pháp được sử dụng bởi cả hai IN
và EXISTS
sẽ chỉ cần đảm bảo rằng bản ghi không tồn tại sau khi cho mỗi hàng trong Orders
, do đó, nó sẽ loại bỏ tất cả các bản sao có thể có trước tiên:
NESTED LOOPS ANTI JOIN
và MERGE ANTI JOIN
sẽ chỉ bỏ qua các từ khóa trùng lặp khi đánh giá HeldOrders
.
- A
HASH ANTI JOIN
sẽ loại bỏ các bản sao khi tạo bảng băm.
Cách tốt nhất là thử các cách tiếp cận khác nhau và kiểm tra các kế hoạch thực thi. – pjp
Trong tình huống của tôi SQL Server 2000, cho các chỉ mục trên các bảng được đề cập đến, truy vấn "Tham gia" là nhanh nhất. CHỌN * TỪ Đơn đặt hàng o TÌM HIỂU HeldOrders h trên o.Order_ID = h.Order_ID và h.Order_ID là null – Stimy