SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Probabilmente restituisce un NULL .
Un NOT IN query non restituirà alcuna riga se qualsiasi NULL s esiste nell'elenco di NOT IN valori. Puoi escluderli esplicitamente usando IS NOT NULL come di seguito.
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)
Oppure riscrivi usando NOT EXISTS invece.
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
Oltre ad avere la semantica che desideri il piano di esecuzione per NOT EXISTS è spesso più semplice come visto qui.
Il motivo della differenza di comportamento è dovuto alla logica a tre valori utilizzata in SQL. I predicati possono restituire True , False o Unknown .
Un WHERE la clausola deve restituire True affinché la riga venga restituita ma ciò non è possibile con NOT IN quando NULL è presente come spiegato di seguito.
'A' NOT IN ('X','Y',NULL) è equivalente a 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
- 'A' <> 'X' =
True - 'A' <> 'Y' =
True - 'A' <> NULL =
Unknown
True AND True AND Unknown restituisce Unknown per le tavole di verità per tre valori logici.
I seguenti collegamenti contengono ulteriori discussioni sulle prestazioni delle varie opzioni.
- Dovrei usare
NOT IN,OUTER APPLY,LEFT OUTER JOIN,EXCEPToNOT EXISTS? NOT INrispetto aNOT EXISTSrispetto aLEFT JOIN / IS NULL:SQL ServerLeft outer joinvsNOT EXISTSNOT EXISTSvsNOT IN