Как заменить NULL в SQL

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

Главная функция: COALESCE

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

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

Если phone NULL → вернётся 'не указан'.

1. Простая замена

SELECT
    user_id,
    COALESCE(phone, 'no phone') AS phone,
    COALESCE(name, 'Unknown') AS name
FROM users;

2. Fallback цепочка

-- первое из не-NULL
SELECT COALESCE(
    primary_email,
    secondary_email,
    phone,
    'no contact'
) AS contact
FROM users;

3. Замена в агрегатах

SUM / AVG возвращает NULL для пустой группы. Защитить:

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

4. Замена в JOIN

LEFT JOIN → строки из правой могут быть NULL:

SELECT
    u.id,
    u.name,
    COALESCE(o.total, 0) AS order_total,
    COALESCE(o.status, 'no ORDER') AS status
FROM users u
LEFT JOIN orders o ON o.user_id = u.id;

5. Замена NULL на значение другой колонки

-- вернуть email, если есть; иначе phone
SELECT COALESCE(email, phone) AS contact FROM users;

-- вернуть name, если есть; иначе username
SELECT COALESCE(name, username) AS display_name FROM users;

6. Варианты в разных СУБД

Postgres / стандарт

COALESCE(a, b, c)

MySQL / SQLite

IFNULL(a, b)   -- только 2 аргумента
COALESCE(a, b, c)  -- тоже работает

Oracle

NVL(a, b)       -- 2 аргумента
NVL2(a, x, y)   -- a не NULL → x, иначе y
COALESCE(a, b, c)  -- стандарт

MSSQL

ISNULL(a, b)    -- 2 аргумента
COALESCE(a, b, c)  -- стандарт

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

7. CASE WHEN для сложной логики

Когда нужна более сложная замена:

SELECT
    CASE
        WHEN phone IS NULL AND email IS NULL THEN 'no contact'
        WHEN phone IS NULL THEN email
        ELSE phone || ' / ' || COALESCE(email, '')
    END AS contact
FROM users;

8. NULLIF — обратная операция

Заменить значение на NULL (если оно = X):

-- если total = 0, вернуть NULL
SELECT NULLIF(total, 0) FROM orders;

-- для деления (избежать /0)
SELECT amount / NULLIF(divisor, 0) AS ratio FROM data;

9. COALESCE + NULLIF для пустых строк

-- если name пустая строка ИЛИ NULL → 'Unknown'
SELECT COALESCE(NULLIF(name, ''), 'Unknown') FROM users;

10. Массовая замена NULL в нескольких колонках

-- приводит все NULL к 0
SELECT
    COALESCE(metric_1, 0) AS metric_1,
    COALESCE(metric_2, 0) AS metric_2,
    COALESCE(metric_3, 0) AS metric_3
FROM data;

В UPDATE:

UPDATE users
SET name = COALESCE(name, 'Unknown'),
    phone = COALESCE(phone, 'не указан')
WHERE name IS NULL OR phone IS NULL;

11. Заменить NULL на значение по умолчанию в колонке

-- установить default для новых записей
ALTER TABLE users ALTER COLUMN status SET DEFAULT 'active';

-- обновить существующие NULL
UPDATE users SET status = 'active' WHERE status IS NULL;

12. Проверка: есть ли NULL

-- количество NULL в колонке
SELECT COUNT(*) FILTER (WHERE col IS NULL) AS nulls FROM TABLE;

-- или универсально
SELECT SUM(CASE WHEN col IS NULL THEN 1 ELSE 0 END) AS nulls FROM TABLE;

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

1. = NULL вместо IS NULL

-- неправильно — всегда FALSE
WHERE col = NULL

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

COALESCE не заменяет это правило.

2. COALESCE(0, ...)

COALESCE ищет первое не-NULL, а не «не-0»:

-- вернёт 0, не 'default'
COALESCE(0, 'default')

Для проверки и на 0, и на NULL — COALESCE + NULLIF:

COALESCE(NULLIF(col, 0), default_value)

3. Несовместимые типы

-- ошибка: string и int
COALESCE(name_text, 0)

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

4. Игнорировать NULL в подсчётах

-- AVG игнорирует NULL (может быть не то, что нужно)
AVG(col)

-- если NULL = 0 для бизнеса
AVG(COALESCE(col, 0))

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

FAQ

COALESCE или IFNULL?

COALESCE — стандарт, везде работает, больше 2 аргументов. Предпочитайте.

Как заменить NULL только в одной ситуации?

CASE WHEN col IS NULL THEN 'x' ELSE col END.

COALESCE в WHERE?

Да: WHERE COALESCE(col, 0) > 100. Но может не использовать индекс на col.

Deleting NULL или fillна default?

Зависит от бизнеса. Default → сохраняете записи. Delete → теряете информацию.


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