sql >> Databasteknik >  >> RDS >> Sqlserver

Finns det något sätt att förenkla en NULL-jämförelse av 2 värden

Ja det kan du, och du kan få optimeraren att känna igen det också.

Paul White har den här lilla snuten :

WHERE NOT EXISTS (
    SELECT d.[Data]
    INTERSECT
    SELECT i.[Data])

Detta fungerar på grund av semantiken för INTERSECT som handlar om nollor. Vad detta säger är "finns det nej rader i underfrågan som består av värde B och värde B", kommer detta endast att uppfyllas om de är olika värden eller om det ena är null och det andra inte. Om båda är null kommer det att finnas en rad med en null.

Om du kontrollerar XML-frågeplanen (inte den grafiska i SSMS) kommer du att se att den kompileras ända ner till d.[Data] <> i.[Data] , men operatorn den använder kommer att ha CompareOp="IS" och inte EQ .

Se hela planen här .

Den relevanta delen av planen är:

                <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>

Jag tycker att optimeraren fungerar mycket bra på det här sättet, snarare än att göra EXISTS / EXCEPT .

Jag uppmanar dig att rösta på Azure Feedback att implementera en riktig operatör



  1. Rekursiva barn-/förälderfrågor i T/SQL

  2. Kan vi specificera graden av parallellism dynamiskt?

  3. MySQL - Komplexiteten för:VÄLJ ANTAL(*) FRÅN MyTable;

  4. Hur kan jag ställa in ett datum till NULL i Yii?