SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Có thể trả về NULL
.
NOT IN
truy vấn sẽ không trả về bất kỳ hàng nào nếu có NULL
s tồn tại trong danh sách NOT IN
các giá trị. Bạn có thể loại trừ chúng một cách rõ ràng bằng cách sử dụng IS NOT NULL
như bên dưới.
SELECT stock.IdStock,
stock.Descr
FROM [Inventory].[dbo].[Stock] stock
WHERE stock.IdStock NOT IN (SELECT foreignStockId
FROM [Subset].[dbo].[Products]
WHERE foreignStockId IS NOT NULL)
Hoặc viết lại bằng NOT EXISTS
thay vào đó.
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
Cũng như có ngữ nghĩa mà bạn muốn kế hoạch thực thi cho NOT EXISTS
thường đơn giản hơn như đã xem ở đây.
Lý do cho sự khác biệt trong hành vi là do ba logic có giá trị được sử dụng trong SQL. Các dự đoán có thể đánh giá thành True
, False
hoặc Unknown
.
A WHERE
mệnh đề phải đánh giá thành True
để trả lại hàng nhưng không thể thực hiện được với NOT IN
khi NULL
hiện như được giải thích bên dưới.
'A' NOT IN ('X','Y',NULL)
tương đương với 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
- 'A' <> 'X' =
True
- 'A' <> 'Y' =
True
- 'A' <> NULL =
Unknown
True AND True AND Unknown
đánh giá thành Unknown
mỗi bảng sự thật cho ba lôgic có giá trị.
Các liên kết sau có một số thảo luận bổ sung về hiệu suất của các tùy chọn khác nhau.
- Tôi có nên sử dụng
NOT IN
,OUTER APPLY
,LEFT OUTER JOIN
,EXCEPT
hoặcNOT EXISTS
? -
NOT IN
so vớiNOT EXISTS
so vớiLEFT JOIN / IS NULL
:Máy chủ SQL -
Left outer join
so vớiNOT EXISTS
-
NOT EXISTS
so vớiNOT IN