Что-либо по сравнению с нулевым значением терпит неудачу. Даже сравнение двух нулевых значений не удастся. Даже! = Потерпит неудачу из-за (IMHO) глупой обработки NULL.
Тем не менее, запросы! = Можно переписать так:
select * from #a a where a.Col not in (select b.Col from #b b)
Последний запрос идентичен второму или последнему запросу, так как порядок сравнения не имеет значения.
Кстати, ваш обходной путь работает просто потому, что вы проверяете нулевое значение в столбце # b.Col и явно конвертируете его в «», что затем позволяет вашему запросу выполнить сравнение строк между ними. Альтернативный способ написания:
select * from #a a, #b b
where a.Col != COALESCE(b.Col, '')