2017-12-20 15 views
0

Ich schreibe eine sehr einfache Unterabfrage in MS SQL, die unerwartete Ergebnisse zurückgibt. Was ich versuche zurückzugeben, ist eine Liste von Acct-Nummern, die in einem Zeitraum, aber nicht in einem anderen Zeitraum existieren. Meine anfängliche Abfrage (unten eingefügt) hat null Zeilen zurückgegeben, was unerwartet ist.SQL-Unterabfrage, die seltsame Ergebnisse zurückgibt

select 
    name1.acct 
from 
    sym.dbo.name as name1 
where 
    name1.processdate = 20171130 
    and name1.type = 0 
    and name1.acct not in 
    (
    select 
     name2.acct 
    from 
     sym.dbo.name as name2 
    where 
     name2.type = 0 
     and name2.processdate = 20171031 
    ) 

Allerdings, wenn ich eine zusätzliche Zeile der Logik der Unterabfrage hinzufügen und ausführen werden die erwarteten Ergebnisse zu mir zurückgekehrt, siehe unten.

select 
    name1.acct 
from 
    sym.dbo.name as name1 
where 
    name1.processdate = 20171130 
    and name1.type = 0 
    and name1.acct not in 
    (
    select 
     name2.acct 
    from 
     sym.dbo.name as name2 
    where 
     name2.type = 0 
     and name2.processdate = 20171031 
     and name2.acct <> '8888888' 
    ) 

Anfangs dachte ich, es auf die Daten bezogen werden kann Typ so habe ich versucht, die acct Nummer varchar konvertieren und int mit dem gleichen Ergebnis (konvertieren Verwendung als werfen im Gegensatz). Kann mir jemand erklären, warum Abfrage eins Null Ergebnisse zurückgegeben und Abfrage zwei die erwarteten Ergebnisse zurückgegeben?

Ich bin mit Microsoft SQL Management Studio 2016.

Dank

+1

Können Sie Beispieldaten zu validieren zeigen, was Sie auf beiden Abfragen für Ergebnisse sehen? –

+0

Sie sollten den Datentyp date oder datetime für Datumsangaben anstelle von ints verwenden. –

Antwort

3

nicht NOT IN Verwenden Sie, vor allem mit Unterabfragen. Es verhält sich nicht wie erwartet - wie Sie gerade gelernt haben. Das Problem? Wenn irgendein Wert, der von der Unterabfrage zurückgegeben wird, NULL ist, dann filtert NOT IN alles heraus.

Verwenden Sie stattdessen NOT EXISTS:

where name1.processdate = 20171130 and 
     name1.type = 0 and 
     not exists (select 1 
        from sym.dbo.name name2 
        where name2.acct = name1.acct and 
         name2.processdate = 20171031 
       ); 
Verwandte Themen