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 — он стандартный и понятный.