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.

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

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:

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’

 

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.

Fumus

Share
Published by
Fumus
Tags: T-SQL

Recent Posts

SQL Server 2019 – static data masking – Du Opfer!

In SQL Server 2016 wurde das sog. dynamic data masking eingeführt. Eine Möglichkeit Daten bei…

5 Jahren ago

MinRole – Oder wie alles etwas einfacher wird

Seit Sharepoint Server 2007 präsentiert sich die Installation immer auf die gleiche Weise. Gerade mal,…

8 Jahren ago

Schritt für Schritt: SQL 2016 – Dynamic Data Masking

Es weihnachtet! Gerade bekam ich von einer Kollegin Plätzchen angeboten mit der Größe eines Diskus…

8 Jahren ago

Schritt für Schritt: SQL Server 2016 – temporal tables

Nein, bitte nicht verwechseln: temporal tables haben nichts zu tun mit temporary tables table variables…

9 Jahren ago

SQL Server 2016 Schritt für Schritt–Installation und First Look

SQL Server 2016.. habe ich schon erwähnt, dass ich den ziemlich cool finde? Wollen wir…

9 Jahren ago

SQL Server 2016 – CTP2

Nach langer Zeit wieder mal eine Artikel von mir.. der mich besonders erfreut. SQL Server…

9 Jahren ago