Seltsames TSQL – Geht nicht geht doch

Vor kurzem bin ich über folgendes seltsames Phänomen gestolpert:

Die folgende Abfrage ist eigentlich nichts besonderes. Allerdings existiert die Spalte "country” nur in der Tabelle Customers, aber nicht in der Tabelle orders.

select * from Customers
    where Country in
    (select country  from orders)

Normalerweise würde man annehmen, das der Optimierer erkennt, dass die Unterabfrage nicht existente Objekte verwendet. Dennoch gibt es keine Fehlermeldung.

Im Ausführungsplan erkennt man, dass der SQL Server versucht, die Tabellen zu joinen, allerdings stellte er auch fest, dass die nicht möglich ist. Daher könnte man annehmen, dass er das Ergebnis des “..where country in ..” als wahr oder falsch interpretiert.

image

Nun würde man annehmen, dass bei einem falschen Statement, zumindest die Abfrage ein Falsch zurückbringt. Aber –oh Wunder – werden alle Zeilen aus customers zurückgegeben.

Aber es kommt noch besser Zwinkerndes Smiley

select * from Customers
    where Country in
    (select country  from orders
        where Country ='germany')

Nun fragen wir in der Tabelle orders nun zusätzlich, die nicht existente Spalte country=’Germany’ ab. Das Ergebnis ist verblüffend:

image

SQL Server filtert die Tabelle customers nach ‘Germany’, obwohl wir im SQL Statement die Tabelle orders filtern wollten. Der Ausführungsplan ist im übrigen der gleiche wie oben. ???

Legen wir noch eins drauf:

select * from Customers
    where 
        Country in
         (select country from orders
            where 
            country like 'U%'
            and 
            CustomerID like 'A%'
        )
order by customerid

Nun würde man annehmen, dass nur noch Ergebniszeilen mit Country = UK als Resultat erscheinen würde, da nur die erste Zeile die Bedingungen erfüllen und ‘UK’ als Ergebnis des Subselects herauskommen sollte . Aber wir sehen, dass die weiteren Zeilen dennoch ausgegeben werden, eben auch ‘USA’

image

 

Das Spiel kann man noch ewig weitertreiben. Bis dato bin ich noch zu keinem vernünftigen Ergebnis gekommen, welche Logik hier dahintersteckt. Fakt ist anscheinend. Das SQL Server das Subselect trotz Obejktfehler verarbeitet und die Spalten aus dem where auf die Abfragetabellen bezieht. Aber der Rest bleibt ein Rätsel.

Wer erkennt hier die Logik? Kommentare erbeten.

Author: Fumus

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert