SQL Server: Warum gibt der Vergleich null = value für NOT IN true zurück?

Warum macht der Vergleich vonvalue zunull return false, außer bei Verwendung einesNOT IN, wo es wahr zurückgibt?

Gab eine Abfrage, um alle Stackoverflow-Benutzer zu finden, diehabe Ein Eintrag

SELECT * FROM Users
WHERE UserID IN (SELECT UserID FROM Posts)

Dies funktioniert wie erwartet; Ich bekomme eine Liste aller Benutzer, die einen Beitrag haben.

Now Abfrage für die Umkehrung; Finde alle Stackoverflow-Benutzer, die nicht Habe einen Beitrag:

SELECT * FROM Users
WHERE UserID NOT IN (SELECT UserID FROM Posts)

Dies gibt keine Datensätze zurück, was falsch ist.

Gegeben hypothetische Daten1

Users              Posts
================   ===============================
UserID  Username   PostID   UserID  Subject
------  --------   -------  ------  ----------------
1       atkins     1        1       Welcome to stack ov...
2       joels      2        2       Welcome all!
...     ...        ...      ...
399573  gt6989b    ...      ...
...     ...        ...      ...
                   10592    null    (deleted by nsl&fbi...
                   ...      ... 

Und nimm die Regeln von NULL an:

NULL = NULL ergibt unbekanntesNULL <> NULL ergibt unbekanntesvalue = NULL wertet unbekannt aus

Wenn wir uns die 2. Abfrage ansehen, sind wir daran interessiert, alle Zeilen zu finden, in denen die Users.UserID @ isnich in der Spalte Posts.UserID gefunden. Ich würde logischerweise wie folgt vorgehen:

Check UserID 1

1 = 1 gibt true zurück. Daraus schließen wir, dass dieser Benutzer einige Posts hat und diese nicht in die Ausgabeliste @ einschließ

Jetzt UserID 2 prüfen:

2 = 1 gibt false zurück, also suchen wir weiter2 = 2 gibt true zurück, sodass wir zu dem Schluss kommen, dass dieser Benutzer einige Posts hat und diese nicht in die Ausgabeliste einbezieht.

Jetzt UserID 399573 prüfen

399573 = 1 gibt false zurück, also suchen wir weiter399573 = 2 gibt false zurück, also suchen wir weiter ...399573 = null gibt unbekannt zurück, also suchen wir weiter ...

Wir haben keine Beiträge von UserID 399573 gefunden, daher würden wir ihn in die Ausgabeliste aufnehmen.

Except SQL Server tut dies nicht. Wenn Sie eine NULL in Ihrem @ habin Liste, dann plötzlich findet es eine Übereinstimmung.Es findet plötzlich eine Übereinstimmung. Plötzlich399573 = null ergibt true.

Warum macht der Vergleich vonvalue zunull return unbekannt, außer wenn es true zurückgibt?

Bearbeite: Ich weiß, dass ich dieses @ umgehen kaunsinni Verhalten durch spezielles Ausschließen der Nullen:

SELECT * FROM Users
WHERE UserID NOT IN (
   SELECT UserID FROM Posts
   WHERE UserID IS NOT NULL)

Aber ich sollte nicht müssen, soweit ich sagen kann, dass die boolesche Logik ohne sie in Ordnung sein sollte - daher meine Frage.

Fußnoten1 hypothetische Daten; wenn es dir nicht gefällt: mach dein unten wieder gut.celko hat jetzt seinen eigenen Tag

Antworten auf die Frage(4)

Ihre Antwort auf die Frage