Sì, puoi farlo riconoscere anche dall'ottimizzatore.
Paul White ha questa canzoncina :
WHERE NOT EXISTS (
SELECT d.[Data]
INTERSECT
SELECT i.[Data])
Questo funziona grazie alla semantica di INTERSECT
che trattano di nulli. Quello che dice è "non ci sono no righe nella sottoquery composta da valore B e valore B", questo sarà soddisfatto solo se sono valori diversi o uno è null e l'altro no. Se entrambi sono null, ci sarà una riga con un null.
Se controlli il piano di query XML (non quello grafico in SSMS), vedrai che viene compilato fino a d.[Data] <> i.[Data]
, ma l'operatore che utilizza avrà CompareOp="IS"
e non EQ
.
Consulta il piano completo qui .
La parte rilevante del piano è:
<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>
Trovo che l'ottimizzatore funzioni molto bene in questo modo, invece di fare EXISTS / EXCEPT
.
Vi esorto a votare per il Feedback di Azure per implementare un operatore adeguato