SELECT foreignStockId
FROM [Subset].[dbo].[Products]
Il renvoie probablement un NULL
.
A NOT IN
La requête ne renverra pas de lignes si un élément de la liste est présent. NULL
existe dans la liste des NOT IN
valeurs. Vous pouvez les exclure explicitement en utilisant IS NOT NULL
comme ci-dessous.
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 réécrire en utilisant NOT EXISTS
à la place.
SELECT stock.idstock,
stock.descr
FROM [Inventory].[dbo].[Stock] stock
WHERE NOT EXISTS (SELECT *
FROM [Subset].[dbo].[Products] p
WHERE p.foreignstockid = stock.idstock)
En plus d'avoir la sémantique que vous voulez que le plan d'exécution de NOT EXISTS
est souvent plus simple comme indiqué ici .
La raison de cette différence de comportement est due au fait que logique à trois valeurs utilisés en SQL. Les prédicats peuvent être évalués à True
, False
ou Unknown
.
A WHERE
doit être évaluée à True
pour que la ligne soit retournée, mais cela n'est pas possible avec NOT IN
quand NULL
est présent comme expliqué ci-dessous.
'A' NOT IN ('X','Y',NULL)
est équivalent à 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)
- 'A' <> 'X' =
True
- 'A' <> 'Y' =
True
- 'A' <> NULL =
Unknown
True AND True AND Unknown
évalue à Unknown
par le tables de vérité pour la logique à trois valeurs .
Les liens suivants proposent des discussions supplémentaires sur les performances des différentes options.
0 votes
Êtes-vous sûr d'avoir des stock.IdStock qui ne sont pas du tout dans foreignStockId ?
0 votes
Avez-vous vraiment des articles dans
Inventory
qui n'est pas dansSubset
?1 votes
Expliquez ce que la requête doit retourner. Actuellement, elle renvoie tous les articles en stock pour lesquels il n'y a pas de produit dans le sous-ensemble qui y fait référence.