Как отфильтровать значения NULL и не NULL в SQL
Что проверяют
Знаете ли вы трёхзначную логику SQL, а не только синтаксис IS NULL. Вопрос простой, поэтому ждут подвохов: почему = NULL не работает и что происходит с NULL в NOT IN, агрегатах и джойнах.
Как отвечать
Базовая часть: WHERE col IS NULL и WHERE col IS NOT NULL. Объясните, почему не = NULL: NULL означает «значение неизвестно», сравнение с ним даёт UNKNOWN, а WHERE пропускает только TRUE. Поэтому col = NULL и col <> NULL возвращают ноль строк.
Сильный ответ идёт дальше:
NOT INсNULL:WHERE id NOT IN (SELECT user_id FROM orders)вернёт пустой результат, если в подзапросе есть хоть одинNULL. ИспользуйтеNOT EXISTS;- отрицание условия:
WHERE status <> 'closed'не вернёт строки соstatus IS NULL. ДобавьтеOR status IS NULLили используйтеIS DISTINCT FROM(в PostgreSQL; в MySQL null-безопасное сравнение делает оператор<=>); - агрегаты:
COUNT(*)считает строки,COUNT(col)только непустые значения,AVGиSUMпропуски игнорируют. Долю пропусков удобно считать черезAVG(CASE WHEN col IS NULL THEN 1.0 ELSE 0 END); - замена:
COALESCE(col, 0)подставляет значение,NULLIF(x, 0)спасает от деления на ноль; - джойны:
NULLне равенNULL, строки с пустым ключом не соединятся. ПослеLEFT JOINусловиеr.id IS NULLнаходит строки без пары.
Для дата-специалиста полезно сравнение с pandas: NaN не равен сам себе, а groupby по умолчанию выкидывает группы с пропуском в ключе (dropna=True).
Где спотыкаются
Пишут WHERE col = NULL и удивляются пустому результату.
Заменяют NULL нулём через COALESCE перед подсчётом среднего и незаметно сдвигают метрику: пропуск и ноль означают разное.
Используют NOT IN с подзапросом по колонке, где допустим NULL, и получают пустую выборку в отчёте без единой ошибки.