Oui, vous pouvez, et vous pouvez également faire en sorte que l'optimiseur le reconnaisse.
Paul White a cette petite chansonnette :
WHERE NOT EXISTS (
SELECT d.[Data]
INTERSECT
SELECT i.[Data])
Cela fonctionne grâce à la sémantique de INTERSECT
qui traitent des valeurs nulles. Ce que cela dit est "y a-t-il non lignes de la sous-requête composée de la valeur B et de la valeur B", cela ne sera satisfait que s'il s'agit de valeurs différentes ou si l'une est nulle et l'autre non. Si les deux sont nuls, il y aura une ligne avec un nul.
Si vous vérifiez le plan de requête XML (pas le plan graphique dans SSMS), vous verrez qu'il se compile jusqu'à d.[Data] <> i.[Data]
, mais l'opérateur qu'il utilise aura CompareOp="IS"
et non EQ
.
Voir le plan complet ici .
La partie pertinente du plan est :
<Predicate>
<ScalarOperator ScalarString="@t1.[i] as [t1].[i] = @t2.[i] as [t2].[i]">
<Compare CompareOp="IS">
<ScalarOperator>
<Identifier>
<ColumnReference Table="@t1" Alias="[t1]" Column="i" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Identifier>
<ColumnReference Table="@t2" Alias="[t2]" Column="i" />
</Identifier>
</ScalarOperator>
</Compare>
</ScalarOperator>
</Predicate>
Je trouve que l'optimiseur fonctionne très bien de cette façon, plutôt que de faire EXISTS / EXCEPT
.
Je vous invite à voter pour le Commentaires Azure pour implémenter un opérateur approprié