SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Provavelmente retorna um
NULL
. Um
NOT IN
a consulta não retornará nenhuma linha se houver NULL
s existe na lista de NOT IN
valores. Você pode excluí-los explicitamente usando IS NOT NULL
como abaixo. 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)
Ou reescreva usando
NOT EXISTS
em vez de. SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
Além de ter a semântica que deseja o plano de execução para
NOT EXISTS
é muitas vezes mais simples como visto aqui. A razão para a diferença de comportamento está na lógica de três valores usada no SQL. Os predicados podem ser avaliados como
True
, False
, ou Unknown
. Um
WHERE
cláusula deve ser avaliada como True
para que a linha seja retornada, mas isso não é possível com NOT IN
quando NULL
está presente conforme explicado abaixo. 'A' NOT IN ('X','Y',NULL)
é equivalente a 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
- 'A' <> 'X' =
True
- 'A' <> 'S' =
True
- 'A' <> NULL =
Unknown
True AND True AND Unknown
avalia como Unknown
de acordo com as tabelas de verdade para três lógicas de valor. Os links a seguir têm algumas discussões adicionais sobre o desempenho das várias opções.
- Devo usar
NOT IN
,OUTER APPLY
,LEFT OUTER JOIN
,EXCEPT
, ouNOT EXISTS
? NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:SQL ServerLeft outer join
vsNOT EXISTS
NOT EXISTS
vsNOT IN