COALESCE в SQL: шпаргалка

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Что делает COALESCE

Возвращает первое не-NULL значение из списка аргументов.

COALESCE(a, b, c, ..., default)

Если все аргументы NULL — возвращает NULL.

Базовые примеры

SELECT COALESCE(NULL, NULL, 'hello', 'world');  -- 'hello'
SELECT COALESCE(NULL, 42, 100);                 -- 42
SELECT COALESCE(NULL, NULL, NULL);              -- NULL

1. Замена NULL на значение по умолчанию

SELECT
    user_id,
    COALESCE(phone, 'не указан') AS phone_display
FROM users;

2. Fallback по приоритету

Сначала проверяем основной email, потом бэкап, потом телефон:

SELECT
    user_id,
    COALESCE(primary_email, secondary_email, phone, 'no_contact') AS contact
FROM users;

3. Агрегаты — обнуление NULL

SUM возвращает NULL для пустой группы — COALESCE спасает:

SELECT
    user_id,
    COALESCE(SUM(total), 0) AS total_spent
FROM orders
GROUP BY user_id;

4. COALESCE в JOIN-ах

Вернуть значение из правой таблицы, если есть, иначе из левой:

SELECT
    u.user_id,
    COALESCE(p.price, o.default_price, 0) AS final_price
FROM users u
LEFT JOIN promo p ON p.user_id = u.user_id
LEFT JOIN options o ON o.user_id = u.user_id;

5. COALESCE + NULLIF (частый приём)

Заменить пустую строку или 0 на NULL, потом на default:

-- получаем "Неизвестно", если name пустой или NULL
SELECT COALESCE(NULLIF(name, ''), 'Неизвестно')
FROM users;

6. COALESCE в ORDER BY

Поставить NULL в конец списка при сортировке:

-- по умолчанию NULL идёт первым (Postgres — последним, но нет гарантии)
-- принудительно — через COALESCE
SELECT * FROM users
ORDER BY COALESCE(age, 999);  -- NULL уходит в конец

Или используйте NULLS LAST (где поддерживается):

SELECT * FROM users ORDER BY age NULLS LAST;

7. COALESCE в WHERE

Чтобы не ломалось сравнение на NULL:

-- стандартное сравнение NULL не работает
SELECT * FROM users WHERE age = 25;  -- пропускает NULL

-- через COALESCE
SELECT * FROM users WHERE COALESCE(age, 0) = 0;  -- пойдут и NULL

Но обычно лучше прямое IS NULL.

8. Дата через COALESCE

-- использовать last_login, если есть, иначе дату регистрации
SELECT
    user_id,
    COALESCE(last_login, created_at) AS last_activity
FROM users;

COALESCE vs аналоги

Функция Работает где Назначение
COALESCE везде (стандарт SQL) вернуть первое не-NULL
ISNULL(a, b) MSSQL, MySQL замена NULL на b (только 2 аргумента)
IFNULL(a, b) MySQL, SQLite то же, что ISNULL
NVL(a, b) Oracle то же
NULLIF(a, b) везде NULL если a = b

Правило: пишите COALESCE. Работает везде, принимает любое количество аргументов.

Типы аргументов

Все аргументы должны быть совместимы по типу. Если разные — нужен CAST:

-- ошибка, если phone text и default_phone integer
COALESCE(phone, 0)

-- правильно
COALESCE(phone, '0')
-- или
COALESCE(CAST(phone AS INTEGER), 0)

Частые ошибки

Ошибка 1: = NULL вместо IS NULL

-- неправильно (всегда NULL, не TRUE)
WHERE column = NULL

-- правильно
WHERE column IS NULL

COALESCE не решает эту проблему — проверяйте через IS NULL.

Ошибка 2: COALESCE(0, ...) с намерением «если 0 или NULL»

COALESCE возвращает первое не-NULL, значение 0 — это не NULL:

-- результат: 0 (не 'default')
COALESCE(0, 'default')

-- если нужно обрабатывать и 0 как пустоту
COALESCE(NULLIF(col, 0), default_value)

Ошибка 3: Забытый default

-- если все NULL — вернёт NULL
COALESCE(a, b, c)

-- лучше:
COALESCE(a, b, c, 'unknown')

Производительность

  • COALESCE быстрый, оптимизируется в любой СУБД
  • Short-circuit evaluation: если первый аргумент не NULL — остальные не вычисляются

Это важно, когда последующие аргументы — дорогие подзапросы:

-- подзапрос не вызывается, если preferred_name не NULL
SELECT COALESCE(preferred_name, (SELECT name FROM users WHERE id = 1))
FROM ...;

Связанные темы

FAQ

Чем COALESCE отличается от ISNULL?

COALESCE — стандарт SQL, работает везде, принимает несколько аргументов. ISNULL — только в MSSQL/MySQL, только два аргумента.

Что вернёт COALESCE, если все аргументы NULL?

NULL. Всегда добавляйте последним аргументом default, если это не желаемый результат.

Можно ли COALESCE в GROUP BY?

Да:

SELECT COALESCE(country, 'unknown'), COUNT(*)
FROM users
GROUP BY COALESCE(country, 'unknown');

Почему COALESCE не обрабатывает пустые строки?

Потому что пустая строка ≠ NULL. Для обработки обоих — COALESCE(NULLIF(col, ''), default).

COALESCE или CASE WHEN?

Если простая замена NULL — COALESCE (короче и читаемее). Если сложная ветвистая логика — CASE.


Тренируйте SQL на реальных задачах — откройте тренажёр с 1500+ вопросами для собеседований аналитиков.