What is the point of outer in a join?

LEFT JOIN and LEFT OUTER JOIN are synonymous so apologies but it sounds like option 2 :-)

The "Outer" join (which preserves unmatched rows) is as opposed to "Inner" (which doesn't).

There are three flavours of outer join. Left, Right, Full (dependent on which unmatched rows are to be preserved).

As SQL doesn't have direct join syntax for any other types of join (such as left/right anti semi join) there is no ambiguity in allowing the OUTER keyword be optional in the grammar.

The LEFT ANTI SEMI JOIN sounds like what you expected LEFT OUTER to do. You can implement that in a variety of ways. Usually NOT EXISTS is preferred but you can use LEFT OUTER JOIN in conjunction with IS NULL to keep only the non matched ones.

This is all confirmed in the "Join type" section of the documentation

LEFT [ OUTER ] Specifies that all rows from the left table not meeting the join condition are included in the result set, and output columns from the other table are set to NULL in addition to all rows returned by the inner join.

The square brackets around the [OUTER] just mean that this is optional but nonetheless the same definition applies.


This would be my preferred way to get what you want, using a correlated sub-query with EXISTS. Assuming you have an index on both tables on switch, port and mac, this should be good performance as well.

SELECT *
FROM SwitchportMac_import i
WHERE NOT EXISTS (
    SELECT TOP (1) 1 
    FROM SwitchportMac sm 
    WHERE sm.switch = i.switch 
      and sm.port = i.port 
      and sm.mac = i.mac
)

from SwitchportMac_import i LEFT OUTER JOIN SwitchportMac sm

This returns rows in i which match in sm.

Correct. That's exactly what a LEFT [OUTER] JOIN does - it gets you everything in the "left" table (i) whether or not it can find a matching row in the "right" table (sm).

To get "new" items (those that appear in the "left" table but not the "right"), you do need to include that "is null" test as well. This is commonly known as an "exclusion join".