Короткий ответ
NULL обозначает отсутствие значения, а не конкретное значение, поэтому любое сравнение с NULL через =, !=, <, > возвращает NULL (не true/false), и строка не попадает в результат WHERE; проверять нужно через IS NULL / IS NOT NULL.
Как это работает подробнее
SQL использует трёхзначную логику (TRUE/FALSE/UNKNOWN); WHERE оставляет только строки, где условие дало TRUE, а UNKNOWN отбрасывается так же, как FALSE. Агрегатные функции COUNT(column), SUM, AVG игнорируют NULL-значения.
Пример кода
example.sql
SELECT COUNT(*) AS total_rows, COUNT(phone) AS rows_with_phone FROM users;
-- COUNT(*) считает все строки, COUNT(phone) пропускает строки где phone IS NULL
SELECT * FROM users WHERE phone = NULL; -- всегда 0 строк, это ошибка в логике
SELECT * FROM users WHERE phone IS NULL; -- корректный способ найти пользователей без телефонаЧто использовать на практике
- Практика. Для замены NULL на значение по умолчанию используют COALESCE(column, 'default'); для подсчёта всех строк включая NULL используют COUNT(*), а не COUNT(column).
Подводные камни
- Ошибка. Пишут WHERE column = NULL вместо WHERE column IS NULL и получают пустой результат без ошибки; не учитывают, что NOT IN с подзапросом, содержащим NULL, возвращает пустой результат для всех строк.