Firebird - особенности сравнения NULL


Большая и важная тонкость заключена в этой статье. :)

Иногда нужно джойнить таблицы по нескольким полям. К примеру

... A INNER JOIN B ON (A.f1=B.f1) AND (A.f2=B.f2) ...

Все проходит хорошо, пока оба поля f1 и f2 ЗАПОЛНЕНЫ, т.е. НЕ ПУСТЫ.

Если f1=NULL или f2=NULL то такое объединение не сработает.
Для такого сравнения начиная с версии 2.0 предусмотрена другая операция:

ТЕОРИЯ:

1. Тест что X и Y различаются или только один из них равен NULL:

SELECT IIF(X is distinct from Y, TRUE, FALSE)

2. Тест, что X и Y равны, и даже в том случае, если равны NULL:

SELECT IIF(X is not distinct from Y, TRUE, FALSE)

Соответственно, по теории наш JOIN по нескольким полям должен выглядеть так:

... A INNER JOIN B ON (A.f1 is not distinct from B.f1) AND (A.f2 is not distinct from B.f2) ...


Дополнительное замечание по поводу сравнений на NULL

Следующая конструкция выполняется медленно:

... WHERE A IS NOT NULL AND B IS NOT NULL ...

Но ее можно значительно ускорить:

... WHERE COALESCE(A,B) IS NOT NULL ...