COALESCE vs ISNULL в SQL — в чём разница и когда что использовать

Коротко

COALESCE — стандартная SQL-функция, которая возвращает первое не-NULL значение из списка аргументов. ISNULL — функция SQL Server, которая принимает ровно два аргумента. COALESCE портируемый и гибче, ISNULL работает только в SQL Server.

Что такое COALESCE

COALESCE принимает любое количество аргументов и возвращает первый, который не равен NULL. Если все аргументы NULL — возвращает NULL. Это часть стандарта ANSI SQL и работает во всех СУБД.

-- Подставить запасное значение, если основное NULL
SELECT
    user_id,
    COALESCE(nickname, first_name, 'Аноним') AS display_name
FROM users;

-- Практический пример: источник трафика
SELECT
    user_id,
    COALESCE(utm_source, referrer, 'direct') AS traffic_source
FROM visits;

COALESCE перебирает аргументы слева направо и возвращает первый не-NULL. Если nickname заполнен — вернёт его. Если нет — попробует first_name. Если и он NULL — вернёт 'Аноним'.

Что такое ISNULL

ISNULL — проприетарная функция SQL Server. Принимает ровно два аргумента: если первый NULL, возвращает второй. Не работает в PostgreSQL, MySQL, ClickHouse и других СУБД.

-- SQL Server
SELECT
    user_id,
    ISNULL(nickname, 'Аноним') AS display_name
FROM users;

-- Замена NULL в числовых столбцах
SELECT
    product_id,
    ISNULL(discount, 0) AS discount
FROM products;

В MySQL есть функция IFNULL с таким же синтаксисом (два аргумента), но это другая функция. Не путайте ISNULL и IFNULL — они из разных СУБД.

Ключевые отличия

COALESCE ISNULL
Стандарт SQL Да (ANSI SQL) Нет (только SQL Server)
Количество аргументов Любое (2+) Ровно 2
Тип результата Наивысший приоритет среди аргументов Тип первого аргумента
Работает в PostgreSQL Да Нет
Работает в MySQL Да Нет (есть IFNULL)
Работает в ClickHouse Да Нет
Вложенность Не нужна Нужна для 3+ значений

Когда использовать COALESCE

  • Вы пишете портируемый SQL (работает везде)
  • Нужно проверить больше двух значений по цепочке
  • Работаете с PostgreSQL, ClickHouse, MySQL или любой СУБД кроме SQL Server
  • Хотите предсказуемое поведение с типами данных
-- Цепочка из трёх источников
SELECT COALESCE(mobile_phone, work_phone, home_phone, 'нет телефона')
FROM contacts;

-- Замена NULL при агрегации
SELECT
    department,
    COALESCE(SUM(bonus), 0) AS total_bonus
FROM employees
GROUP BY department;

Когда использовать ISNULL

  • Вы работаете только в SQL Server и не планируете миграцию
  • Нужно ровно два аргумента (простая замена NULL)
  • Хотите, чтобы тип результата совпадал с типом первого аргумента
-- SQL Server: простая замена NULL
SELECT
    order_id,
    ISNULL(shipping_cost, 0) AS shipping_cost
FROM orders;

Типичная ошибка

Разница в определении типа результата может привести к неожиданным обрезаниям данных:

-- SQL Server: ISNULL обрезает строку!
DECLARE @name VARCHAR(5) = NULL;
SELECT ISNULL(@name, 'Длинное имя');
-- Результат: 'Длинн' (обрезано до VARCHAR(5))

-- COALESCE не обрезает
SELECT COALESCE(@name, 'Длинное имя');
-- Результат: 'Длинное имя' (полная строка)

ISNULL приводит результат к типу первого аргумента (VARCHAR(5)), а COALESCE выбирает тип с наивысшим приоритетом. Это классическая ловушка SQL Server.

-- Ещё одна ловушка: ISNULL с вложенностью
-- Нужно проверить три значения в SQL Server без COALESCE
SELECT ISNULL(a, ISNULL(b, ISNULL(c, 'default')))
FROM my_table;

-- С COALESCE — чисто и читаемо
SELECT COALESCE(a, b, c, 'default')
FROM my_table;

Вопросы с собеседований

Чем COALESCE отличается от ISNULL? — COALESCE — стандарт SQL, принимает любое количество аргументов. ISNULL — функция SQL Server, принимает ровно два. COALESCE портируемый и работает во всех СУБД.

Что вернёт COALESCE(NULL, NULL, NULL)? — NULL. Если все аргументы NULL, COALESCE возвращает NULL.

Как заменить NULL на 0 в PostgreSQL?COALESCE(column, 0). ISNULL в PostgreSQL не существует. Альтернатива — NULLIF для обратной задачи (превратить значение в NULL).

В чём подвох с типами данных у ISNULL? — ISNULL приводит результат к типу первого аргумента. Если первый аргумент VARCHAR(5), а замена — длинная строка, она будет обрезана. COALESCE выбирает тип с наивысшим приоритетом.

Что такое NULLIF и чем он отличается от COALESCE? — NULLIF(a, b) возвращает NULL, если a = b, иначе a. Это обратная операция: COALESCE превращает NULL в значение, NULLIF превращает значение в NULL. Классическое применение: NULLIF(x, 0) для защиты от деления на ноль.

FAQ

Есть ли аналог ISNULL в PostgreSQL?

Прямого аналога нет. Используйте COALESCE — он делает то же самое и даже больше. Если нужна проверка на NULL, есть также конструкция IS NOT DISTINCT FROM.

COALESCE и CASE WHEN — это одно и то же?

По сути COALESCE(a, b) — это сокращение для CASE WHEN a IS NOT NULL THEN a ELSE b END. Но COALESCE удобнее для цепочки значений и читается чище.

Влияет ли COALESCE на производительность?

Практически нет. COALESCE — простая операция, которая проверяет значения последовательно. На индексы не влияет, если не оборачивать индексированный столбец: WHERE COALESCE(col, 0) > 10 не сможет использовать индекс по col.

Что использовать в ClickHouse для замены NULL?

В ClickHouse работает COALESCE. Есть также ifNull(a, b) — аналог ISNULL, но с другим именем. Для аналитических запросов рекомендуется COALESCE — он стандартный и понятный.