• The behaviour posted in completly explainable. SQL-Server is working according to the SQL-Standards.

    What most people don't know is that SQL "boolean" logic is actually a tripartite logic (a logic with three states) governed (simplified) by these additional rules:

    • state: true, false, undefined
    • a comparsion (==,<>,>,< ) with NULL is undefined (this is the reason for the IS NULL operator)
    • A and undefined is undefined
    • A or undefined is A
    • not undefined is undefined

    A SELECT will deliver all rows where the WHERE clause evaluates to true.

    A LEFT OUTER JOIN will match all rows from table A with all rows from table B for which the ON clause evaluatues to true. If there is no such match then it will deliver row A once with all SELECTed fields from B set to NULL.

    If you apply this to the last example you can explain it:

    select *

    from a

    left outer join b

    on a.id = b.id

    where b.id <> 8

    This will deliver the following result before applying the WHERE clause:

    id          id         

    ----------- ----------- 

    1           NULL

    2           2

    3           NULL

    4           4

    5           NULL

    6           6

    7           NULL

    8           8

    The only rows where the WHERE clause evaluates to true are 2,4,6. Row 8 evaluates to false, all other to undefined.

    select *

    from a

    left outer join b

    on a.id = b.id

      and b.id <> 8

    id          id         

    ----------- -----------

    1           NULL

    2           2

    3           NULL

    4           4

    5           NULL

    6           6

    7           NULL

    8           NULL

    This examples select all rows from A with rows from B which matching ID unequal to 8 (2,4,6) and selects one row from A with a NULL row from B.

    One must be very careful when doing logic with NULL values.