SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Gibt wahrscheinlich ein NULL zurück .
A NOT IN Die Abfrage gibt keine Zeilen zurück, wenn NULL vorhanden ist s existiert in der Liste NOT IN Werte. Sie können sie explizit mit IS NOT NULL ausschließen wie unten.
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)
Oder schreiben Sie mit NOT EXISTS um stattdessen.
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
Sowie die Semantik, dass Sie den Ausführungsplan für NOT EXISTS haben möchten ist oft einfacher als hier zu sehen.
Der Grund für das unterschiedliche Verhalten liegt in der dreiwertigen Logik, die in SQL verwendet wird. Prädikate können als True ausgewertet werden , False , oder Unknown .
Ein WHERE -Klausel muss zu True ausgewertet werden damit die Zeile zurückgegeben wird, was aber mit NOT IN nicht möglich ist wenn NULL vorhanden ist, wie unten erklärt.
'A' NOT IN ('X','Y',NULL) entspricht 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
- 'A' <> 'X' =
True - 'A' <> 'Y' =
True - 'A' <> NULL =
Unknown
True AND True AND Unknown wird zu Unknown ausgewertet nach den Wahrheitstabellen für dreiwertige Logik.
Die folgenden Links enthalten zusätzliche Diskussionen über die Leistung der verschiedenen Optionen.
- Soll ich
NOT INverwenden ,OUTER APPLY,LEFT OUTER JOIN,EXCEPT, oderNOT EXISTS? NOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:SQL-ServerLeft outer joinvsNOT EXISTSNOT EXISTSvsNOT IN