Dokładnie tak. NULL reprezentuje nieznaną wartość, a nie określoną wartość (to nie to samo co NULL w C lub nil w Ruby itp.) W SQL, jeśli porównasz coś z nieznaną wartością, wynik również jest nieznany. I nie dostaniesz wierszy, w których WHERE stan jest nieznany.
Spróbuj tego:
SELECT NULL <> 2;
a zobaczysz NULL w rezultacie.
Spróbuj tego:
SELECT * FROM t WHERE NULL;
i żadne wiersze nie wyjdą, nawet jeśli tabela t jest ogromny.
Jeśli naprawdę potrzebujesz tego, co powiedziałeś, że chcesz (a nie popieram tego), możesz zrobić coś takiego:
SELECT T.f1, T.f2
FROM (SELECT NULL f1, 'a' f2) T
WHERE ((T.f1 IS NULL OR T.f2 IS NULL)
AND (T.f1 IS NOT NULL OR T.f2 IS NOT NULL))
OR T.f1 <> T.f2