Sí, puedes, y puedes hacer que el optimizador también lo reconozca.
Paul White tiene esta cancioncilla :
WHERE NOT EXISTS (
SELECT d.[Data]
INTERSECT
SELECT i.[Data])
Esto funciona debido a la semántica de INTERSECT
que tratan con valores nulos. Lo que dice es "¿hay no filas en la subconsulta compuesta por el valor B y el valor B”, esto solo se cumplirá si son valores diferentes o uno es nulo y el otro no. Si ambos son nulos, habrá una fila con un nulo.
Si revisa el plan de consulta XML (no el gráfico en SSMS), verá que se compila hasta d.[Data] <> i.[Data]
, pero el operador que usa tendrá CompareOp="IS"
y no EQ
.
Consulta el plan completo aquí .
La parte relevante del plan es:
<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>
Encuentro que el optimizador funciona muy bien de esta manera, en lugar de hacer EXISTS / EXCEPT
.
Le insto a que vote por Comentarios de Azure implementar un operador adecuado