Как правильно проверить значение на NULL в SQL?
- Почему WHERE column = NULL ничего не находит?
- Как работает NULL в агрегатах и NOT IN?
NULL — «неизвестно», и любое сравнение с ним даёт UNKNOWN, а не TRUE. Поэтому проверяют только IS NULL и IS NOT NULL.
x = NULLиx <> NULLникогда не истинны- Агрегаты (sum, avg, count(col)) пропускают NULL; count(*) — считает строки
NOT IN (подзапрос с NULL)вернёт пустой результат — ловушка
А ещё COALESCE(x, 0) подставляет значение по умолчанию; IS DISTINCT FROM сравнивает с учётом NULL
Подробно
Трёхзначная логика. В SQL есть TRUE, FALSE и UNKNOWN. Сравнение с NULL (=, <>, >) даёт UNKNOWN, а WHERE пропускает только TRUE. Поэтому WHERE middle_name = NULL не вернёт ничего, а WHERE middle_name <> 'А' не вернёт строки с NULL.
Правильно: IS NULL, IS NOT NULL, а для сравнения двух значений с учётом NULL — IS DISTINCT FROM / IS NOT DISTINCT FROM.
Агрегаты: sum, avg, min, max, count(колонка) игнорируют NULL; count(*) считает все строки. Среднее по колонке с NULL — среднее по непустым значениям. Сумма пустого множества — NULL, а не 0.
Ловушка NOT IN: если подзапрос вернул хотя бы один NULL, x NOT IN (…) для любого x даёт UNKNOWN — результат пуст. Надёжнее NOT EXISTS.
Ещё: NULL в сортировке идут в конце (PostgreSQL, по возрастанию) или в начале — управляется NULLS FIRST/LAST; в UNIQUE несколько NULL допустимы; COALESCE возвращает первый не-NULL аргумент.
Пример
SELECT * FROM users WHERE phone IS NULL; -- правильно
SELECT count(*), count(phone) FROM users; -- все строки / с телефоном
SELECT * FROM a WHERE id NOT IN (SELECT a_id FROM b); -- пусто, если в b есть NULL
SELECT * FROM a WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.a_id = a.id); -- надёжноЧто хотят услышать
- IS NULL вместо сравнения и почему.
- Трёхзначная логика.
- NULL в агрегатах и ловушка NOT IN — плюс.
Частые ошибки
= NULLв условии.NOT INс подзапросом, который может вернуть NULL.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗field = NULL
- ✓field IS NULL
- ✗field == NULL
- ✗field EQUALS NULL
Что спросят дальше
- Как count(*) отличается от count(column)?
- Что такое three-valued logic?
Разбор темы
- SQL: операторы, NULL и фильтрация
Группы команд, логический порядок SELECT, трёхзначная логика NULL, разница WHERE/HAVING и оконные функции — с ловушками, на которых валятся на собеседовании.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.