Блог
SQL

COALESCE и NULLIF в SQL: как работать с NULL

COALESCE и NULLIF — две встроенные SQL-функции для работы с NULL (отсутствующим значением). COALESCE(a, b, c, ...) возвращает первый среди аргументов, который не равен NULL — обычно используется, чтобы подставить значение по умолчанию вместо NULL. NULLIF(a, b) — обратная операция: возвращает NULL, если a равно b, иначе возвращает a — используется, чтобы превратить конкретное «пустое» значение (например, 0 или пустую строку) в настоящий NULL.

Что делает COALESCE в SQL?

SELECT
name,
COALESCE(phone, email, 'нет контакта') AS contact
FROM users;

COALESCE проверяет аргументы слева направо и возвращает первый, который не NULL. В примере: если у пользователя есть phone — вернётся он; если phone пуст, но есть email — вернётся email; если оба пустые — вернётся строка 'нет контакта'. COALESCE может принимать любое количество аргументов, а не только два — это отличает его от более старой и менее переносимой конструкции ISNULL/NVL, которые в разных СУБД называются по-разному и обычно принимают только два аргумента.
COALESCE и его аналоги в разных СУБД:
— COALESCE — PostgreSQL, MySQL, SQL Server, Oracle, любое количество аргументов, стандарт ANSI SQL.
— ISNULL — только SQL Server, 2 аргумента, нестандартная (T-SQL).
— NVL — только Oracle, 2 аргумента, нестандартная (PL/SQL).

Зачем COALESCE нужен в агрегатных функциях и вычислениях?

SELECT
user_id,
SUM(COALESCE(discount, 0)) AS total_discount
FROM orders
GROUP BY user_id;

NULL в арифметике «заражает» результат: 5 + NULL даёт NULL, а не 5. Если в столбце discount часть строк содержит NULL (скидки не было), а не 0, прямой SUM(discount) их просто пропустит — это не ошибка, а корректное поведение SUM, которая игнорирует NULL. Но в других вычислениях NULL ведёт себя иначе: например, при построчном сложении в SELECT наличие NULL в одной операции даёт NULL для всей строки. Если такие строки нужно явно посчитать как «скидка 0», COALESCE(discount, 0) подставляет 0 до вычисления и защищает от неожиданного NULL в результате.

Что делает NULLIF в SQL?

SELECT
order_id,
amount,
amount / NULLIF(quantity, 0) AS price_per_unit
FROM orders;

Классический пример использования NULLIF — защита от деления на ноль. В PostgreSQL, SQL Server и Oracle, если quantity равен 0, обычное деление amount / quantity вызывает ошибку деления на ноль, и весь запрос падает. В MySQL то же самое деление на 0 по умолчанию просто тихо возвращает NULL, без ошибки — поведение отличается от остальных СУБД. NULLIF(quantity, 0) превращает 0 в NULL перед делением, а деление любого числа на NULL везде одинаково даёт NULL (не ошибку) — так price_per_unit для таких строк предсказуемо становится NULL во всех СУБД, а не только там, где деление на ноль не вызывает ошибку.

Чем NULL отличается от 0 и пустой строки?

NULL означает «значение неизвестно» или «значение отсутствует», а не «нулевое» или «пустое». 0 — это конкретное числовое значение, '' (пустая строка) — конкретное текстовое значение, и оба они равны сами себе в обычном сравнении. NULL не равен ничему, даже другому NULL — сравнение NULL = NULL возвращает NULL (не TRUE), поэтому для проверки на NULL используется IS NULL / IS NOT NULL, а не = NULL.
Сравнение значений:
— 0 (число): x = x → TRUE, x = NULL → NULL.
— '' (пустая строка): x = x → TRUE, x = NULL → NULL.
— NULL (отсутствие значения): x = x → NULL, x = NULL → NULL.
Эта путаница — одна из самых частых причин логических ошибок в SQL-запросах у новичков: условие WHERE discount = NULL не найдёт ни одной строки, даже если в таблице есть строки с NULL в этом столбце, потому что сравнение с NULL через = никогда не возвращает TRUE.

Частые вопросы про NULL, COALESCE и NULLIF

Чем COALESCE отличается от ISNULL/NVL? COALESCE — стандартная функция SQL (ANSI SQL), принимает любое количество аргументов и работает одинаково в PostgreSQL, MySQL, SQL Server и Oracle. ISNULL (SQL Server) и NVL (Oracle) — нестандартные, специфичные для конкретной СУБД функции, обычно принимающие только два аргумента. Если нужна переносимость между СУБД — предпочтительнее COALESCE.
Почему WHERE column = NULL не находит строки с NULL? Потому что оператор = с NULL в любой части сравнения всегда возвращает NULL (не TRUE и не FALSE), а строки, у которых условие WHERE дало NULL, в результат не попадают — так же, как и при FALSE. Для поиска строк с отсутствующим значением нужно использовать WHERE column IS NULL.
COUNT(column) считает строки с NULL? Нет. COUNT(column) считает только строки, где значение этого столбца не NULL. COUNT(*) считает все строки независимо от NULL. Если нужно посчитать строки с NULL отдельно — можно использовать COUNT(*) - COUNT(column) или SUM(CASE WHEN column IS NULL THEN 1 ELSE 0 END).
Можно ли использовать COALESCE с разными типами данных? Аргументы COALESCE должны быть совместимы по типу (либо одного типа, либо СУБД может привести их к общему типу автоматически). COALESCE(1, 'текст') в большинстве СУБД вызовет ошибку или неожиданное приведение типов — на практике аргументы стоит явно приводить к одному типу (CAST), если они изначально разные.

Закрепить работу с NULL, COALESCE и NULLIF на практике

Ошибка WHERE discount = NULL, которая молча не находит ни одной строки, — классическая ловушка, в которую попадает почти каждый новичок хотя бы раз. Проверить на практике, как COALESCE, NULLIF и трёхзначная логика NULL ведут себя в разных СУБД (включая различие в делении на 0 между MySQL и PostgreSQL, разобранное выше), можно на тренажёре SQL Arena от Quality Academy — с переключением диалекта и AI-ментором, который укажет на ошибку. Больше 800 задач, часть — бесплатно.

-------

Полезные ссылки школы

Сайт Quality Academy:
https://quality-academy.ru/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena