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 INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:SQL ServerLeft outer joinvsNOT EXISTSNOT EXISTSvsNOT IN