Функция NULLIF() в SQL: защита деления на ноль и не только
NULLIF(a, b) возвращает NULL, если оба аргумента равны, и значение a в остальных случаях. Самое частое применение у аналитика — защита от деления на ноль: NULLIF(знаменатель, 0) превращает нулевой знаменатель в NULL, и деление даёт NULL вместо ошибки. Также NULLIF удобна, чтобы «занулить» специальные маркеры вроде пустой строки.
Синтаксис
NULLIF(значение, значение_с_которым_сравнить)
Примеры использования
Пример 1: Конверсия без ошибки деления на ноль
SELECT step,
ROUND(converted::numeric / NULLIF(visitors, 0) * 100, 1) AS cr_pct
FROM funnel;
NULLIF сравнивает ровно два значения на равенство — не путай с COALESCE (которая выбирает первое не-NULL). Если знаменатель может быть NULL ещё до NULLIF, деление всё равно даст NULL — это ожидаемо. И помни про приведение типов: целочисленное деление обрежет дробную часть, поэтому оборачивай числитель в ::numeric.
Где спрашивают на собеседовании
NULLIF почти всегда всплывает вместе с расчётом конверсии, retention и любых долей — интервьюер проверяет, помнишь ли ты про деление на ноль. Идеальная связка: ROUND(x::numeric / NULLIF(y, 0) * 100, 1).
FAQ: частые вопросы про NULLIF
Как NULLIF защищает от деления на ноль?
NULLIF(y, 0) возвращает NULL, если y равно 0. Деление на NULL даёт NULL (а не ошибку), поэтому запрос не падает на строках с нулевым знаменателем.
Чем NULLIF отличается от COALESCE?
NULLIF превращает значение в NULL при совпадении с эталоном (обратная операция). COALESCE, наоборот, заменяет NULL на первое непустое значение. Часто их комбинируют.
Можно ли применять NULLIF не к числам?
Да, к любому типу: например, NULLIF(status, 'unknown') вернёт NULL для строки-заглушки, что удобно перед агрегатами, игнорирующими NULL.