Функция COALESCE в SQL: синтаксис и примеры для PostgreSQL, MySQL и SQL Server

COALESCE возвращает первый из своих аргументов, который не равен NULL, и пишется одинаково в PostgreSQL, MySQL, SQL Server, Oracle и SQLite.

Разбираем синтаксис, замену NULL в отчётах и суммах, связку с NULLIF и разницу с ISNULL, IFNULL и NVL.

Все запросы прогнаны в MySQL 8.0, PostgreSQL 17 и SQLite, вывод приложен.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 3119 статей автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3773 экспертных мнения Подписаться на Телеграм-канал
Обложка: Функция COALESCE в SQL: синтаксис и примеры для PostgreSQL, MySQL и SQL Server

COALESCE в SQL возвращает первый из своих аргументов, который не равен NULL. Аргументы проверяются слева направо: COALESCE(telegram, phone, email, 'нет контакта') вернёт телеграм, если он заполнен, иначе телефон, иначе почту, а если пусто всё, то строку «нет контакта». Когда NULL все аргументы, результат тоже NULL.

Функция входит в стандарт SQL и одинаково пишется в PostgreSQL, MySQL, SQL Server, Oracle и SQLite. Ниже синтаксис, примеры с выводом, связка с NULLIF и разница с ISNULL, IFNULL и NVL. Если путаетесь, чем NULL отличается от пустой строки, начните с разбора NULL в SQL.

CheckroiCheckroiПодборка курсов по SQL422 курса • 40 школСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Синтаксис COALESCE и как она работает

Рой разбирает SQL-запрос с подстановкой значений вместо пустых
COALESCE(выражение1, выражение2, ..., выражениеN)

Порядок вычисления такой:

  1. СУБД берёт первый аргумент. Если он не NULL, это и есть ответ.
  2. Если NULL, переходит ко второму, потом к третьему.
  3. Первый непустой аргумент возвращается, остальные правее него в PostgreSQL и Oracle даже не вычисляются.
  4. Если NULL оказались все, функция возвращает NULL.

Самый короткий пример, по образцу из справки Microsoft. Вывод здесь и ниже показан в формате MySQL. В PostgreSQL и SQLite значения те же, а где они расходятся, это сказано отдельно.

SELECT COALESCE(NULL, NULL, 'третье', 'четвёртое') AS result;

+--------+
| result |
+--------+
| третье |
+--------+

Справка PostgreSQL прямо говорит, что аргументы правее первого непустого не вычисляются, Oracle называет то же самое short-circuit evaluation. На практике это значит, что тяжёлое выражение в конце списка не тормозит запрос, пока до него не дошла очередь.

По сути COALESCE служит короткой записью выражения CASE. SQL Server так её и выполняет: оптимизатор переписывает вызов в CASE WHEN выражение1 IS NOT NULL THEN выражение1 ... END, это описано в справке по Transact-SQL. Русская версия этой страницы, кстати, называется «СЛИЯНИЕ», хотя в запросе пишется всё равно COALESCE.

Пример на таблице: подставляем значение вместо NULL

Возьмём таблицу клиентов, где у каждого заполнен свой набор контактов:

CREATE TABLE clients (id INT, name VARCHAR(50), telegram VARCHAR(50), phone VARCHAR(20), email VARCHAR(50));
INSERT INTO clients VALUES
  (1, 'Анна', '@anna_k', NULL, 'anna@mail.ru'),
  (2, 'Борис', NULL, '+7 900 111-22-33', NULL),
  (3, 'Вера', NULL, '  ', 'vera@yandex.ru'),
  (4, 'Глеб', NULL, NULL, NULL);

Нужен один столбец «как связаться» с приоритетом телеграм → телефон → почта:

SELECT name, COALESCE(telegram, phone, email, 'нет контакта') AS contact
FROM clients
ORDER BY id;

+-------+------------------+
| name  | contact          |
+-------+------------------+
| Анна  | @anna_k          |
| Борис | +7 900 111-22-33 |
| Вера  |                  |
| Глеб  | нет контакта     |
+-------+------------------+

Анна и Борис получили первый заполненный контакт, Глеб получил значение по умолчанию. А у Веры пусто, хотя почта есть. Причина в том, что телефон у неё записан двумя пробелами: для COALESCE это обычная строка, и до почты очередь не дошла. Как это лечится, показано в разделе про NULLIF ниже.

Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

COALESCE с SUM, AVG и в расчётах

SUM, AVG и MAX на пустом наборе строк возвращают NULL. Чаще всего это вылезает в LEFT JOIN, когда у строки слева нет пары справа:

CREATE TABLE orders (client_id INT, amount INT);
INSERT INTO orders VALUES (1, 1500), (1, 2300), (2, 900);

SELECT c.name,
       SUM(o.amount)              AS raw_sum,
       COALESCE(SUM(o.amount), 0) AS total
FROM clients c
LEFT JOIN orders o ON o.client_id = c.id
GROUP BY c.id, c.name
ORDER BY c.id;

+-------+---------+-------+
| name  | raw_sum | total |
+-------+---------+-------+
| Анна  |    3800 |  3800 |
| Борис |     900 |   900 |
| Вера  |    NULL |     0 |
| Глеб  |    NULL |     0 |
+-------+---------+-------+

В отчёте ноль читается как «заказов не было», а пустая ячейка выглядит как «данных нет» или сбой выгрузки. Поэтому сумму по LEFT JOIN обычно оборачивают в COALESCE. С функцией COUNT этого делать не нужно: на пустой группе она сама вернёт 0.

То же правило работает в арифметике. price * NULL даёт NULL, поэтому скидку, которой может не быть, пишут так: price - COALESCE(discount, 0).

NULLIF и COALESCE вместе

NULLIF делает обратную операцию: NULLIF(a, b) возвращает NULL, если a равно b, и a во всех остальных случаях. Вдвоём эти функции решают две частые задачи.

Пустые строки и пробелы

Вернёмся к Вере. Обрезаем пробелы, пустую строку превращаем в NULL, а NULL заменяем текстом:

SELECT name, COALESCE(NULLIF(TRIM(phone), ''), 'не указан') AS phone
FROM clients
ORDER BY id;

+-------+------------------+
| name  | phone            |
+-------+------------------+
| Анна  | не указан        |
| Борис | +7 900 111-22-33 |
| Вера  | не указан        |
| Глеб  | не указан        |
+-------+------------------+

Деление на ноль

Если делитель может быть нулём, NULLIF превращает его в NULL. Деление на NULL даёт NULL вместо ошибки, а COALESCE подставляет понятный результат:

SELECT 100 / NULLIF(0, 0)              AS ratio,
       COALESCE(100 / NULLIF(0, 0), 0) AS ratio_safe;

+-------+------------+
| ratio | ratio_safe |
+-------+------------+
|  NULL |     0.0000 |
+-------+------------+

PostgreSQL и SQLite на этом запросе показывают в ratio_safe просто 0.

COALESCE, ISNULL, IFNULL и NVL: чем отличаются

Четыре похожих ключа разной формы на светлом столе

У каждой СУБД есть своя функция на два аргумента, которая делает почти то же самое. Разница в типе результата и в поведении на краевых случаях.

Функция Где работает Аргументов Что важно знать
COALESCE везде любое число (в Oracle и SQLite не меньше двух) стандарт SQL, тип результата берётся самый «старший» из аргументов
ISNULL(a, b) SQL Server 2 тип результата берётся у первого аргумента, длинная замена обрезается
IFNULL(a, b) MySQL, SQLite 2 в MySQL тип результата берётся более общий из двух
NVL(a, b) Oracle 2 при разных типах Oracle неявно приводит один к другому, а если не может, выдаёт ошибку
ISNULL(a) MySQL 1 это проверка, а не замена: вернёт 1 или 0

В PostgreSQL нет ни ISNULL, ни IFNULL, ни NVL: на SELECT IFNULL(NULL, 1) PostgreSQL 17 отвечает function ifnull(unknown, integer) does not exist. Замену NULL там делают через COALESCE. По справке PostgreSQL, COALESCE даёт возможности, похожие на NVL и IFNULL из других СУБД.

COALESCE и ISNULL в SQL Server

Microsoft перечисляет пять различий между ними. Их стоит знать каждому SQL-разработчику, который пишет процедуры под SQL Server:

  • Число вычислений. ISNULL — функция, она вычисляется один раз. Аргументы COALESCE могут вычисляться несколько раз, потому что выражение переписано в CASE.
  • Тип результата. ISNULL берёт тип первого параметра, а COALESCE выбирает тип с наивысшим приоритетом среди всех аргументов.
  • Допустимость NULL. ISNULL(col, 0) считается выражением NOT NULL, поэтому вычисляемый столбец с ним может стать первичным ключом. С COALESCE(col, 0) такой ключ создать не получится. Как объявлять таблицы и ключи в SQL Server, показано в статье о создании базы данных.
  • Нетипизированный NULL. В ISNULL литерал NULL превращается в int, а для COALESCE хотя бы одно значение должно иметь тип.
  • Количество аргументов. У ISNULL их ровно два, у COALESCE сколько угодно.

Из второго пункта вытекает ловушка с обрезкой строк. В справке по ISNULL сказано, что значение замены «может усекаться, если значение replacement_value длиннее, чем check_expression». Если проверяемый столбец объявлен как VARCHAR(5), а замена длиннее, в результат может попасть только её начало. Поэтому для строк с разной длиной надёжнее COALESCE или явный CAST.

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

Рой радуется, что нашёл пустую ячейку, из-за которой ломался отчёт

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

Хотим вывести «нет оценки» вместо пустой оценки, где score хранится целым числом:

CREATE TABLE ratings (course VARCHAR(20), score INT);
INSERT INTO ratings VALUES ('SQL', 5), ('SQL', 4), ('SQL', NULL), ('SQL', NULL);

SELECT score, COALESCE(score, 'нет оценки') AS score_text FROM ratings;

MySQL и SQLite молча вернут смешанный столбец. PostgreSQL 17 останавливает запрос с ошибкой:

invalid input syntax for type integer: "нет оценки"

Решение: привести число к строке явно.

-- PostgreSQL, SQL Server
SELECT score, COALESCE(CAST(score AS VARCHAR(10)), 'нет оценки') AS score_text FROM ratings;
-- MySQL: CAST AS VARCHAR там даёт синтаксическую ошибку, нужен CHAR
SELECT score, COALESCE(CAST(score AS CHAR), 'нет оценки') AS score_text FROM ratings;

+-------+------------+
| score | score_text |
+-------+------------+
|     5 | 5          |
|     4 | 4          |
|  NULL | нет оценки |
|  NULL | нет оценки |
+-------+------------+

Ноль вместо NULL ломает среднее

AVG пропускает NULL. Если заменить их нулями, курс без оценок будет выглядеть как курс с плохими оценками:

SELECT AVG(score)              AS avg_real,
       AVG(COALESCE(score, 0)) AS avg_zero
FROM ratings;   -- оценки: 5, 4, NULL, NULL

+----------+----------+
| avg_real | avg_zero |
+----------+----------+
|   4.5000 |   2.2500 |
+----------+----------+

Правило простое: COALESCE подставляет значение для показа и для сумм. В среднем, минимуме и медиане NULL лучше оставить как есть.

Пустая строка вместо NULL

Симптом: в списке «как связаться» пустые ячейки, хотя запасные контакты есть. Причина та же, что у Веры: в PostgreSQL, MySQL и SQLite пустая строка и пробелы считаются обычными значениями. Решение: COALESCE(NULLIF(TRIM(phone), ''), ...).

ISNULL из SQL Server в MySQL

Запрос ISNULL(phone, 'не указан'), перенесённый из SQL Server, в MySQL падает с ошибкой Incorrect parameter count in the call to native function 'ISNULL'.

В MySQL ISNULL(expr) принимает один аргумент и отвечает 1 или 0, так написано в справочнике операторов сравнения.

Решение: замену там делают через IFNULL (см. функции управления потоком) или COALESCE, и COALESCE удобнее: тот же запрос заработает и в PostgreSQL.

Подзапрос внутри COALESCE в SQL Server

В COALESCE((SELECT ...), 1) подзапрос вычисляется дважды. По справке Microsoft, при уровне изоляции READ COMMITTED в многопользовательской среде такой код может вернуть NULL. Там же три выхода: уровень SNAPSHOT ISOLATION, замена COALESCE на ISNULL или перенос подзапроса во вложенный SELECT, который проверяют уже через CASE.

Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Где освоить SQL системно

COALESCE встречается почти в каждом отчётном запросе, но это одна функция из многих. Дальше обычно идут оконные функции, подзапросы и оптимизация. Если хотите освоить язык целиком, а не по одной функции, сравните курсы по SQL в подборке ниже.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Нейросети для рабочих задач
Перейти на сайт курса
SkillboxSkillbox31 290 ₽ - 1 месяцОбзор курса
SQL для анализа данных
Перейти на сайт курса
SkillboxSkillbox52 353 ₽6203 ₽/мес.2 месяцаОбзор курса
SQL-разработчик: тариф PRO
Перейти на сайт курса
Академия ЭдюсонЭдюсон89 900 ₽7491 ₽/мес.2 месяцаОбзор курса
SQL-разработчик: тариф Базовый
Перейти на сайт курса
Академия ЭдюсонЭдюсон79 900 ₽3329 ₽/мес.3 месяцаОбзор курса
SQL с нуляSkyproSkypro134 640 ₽5500 ₽/мес.12 месяцевОбзор курса

Больше программ — в полном каталоге курсов по SQL

Часто задаваемые вопросы

Что такое COALESCE в SQL простыми словами?

Функция, которая возвращает первый из своих аргументов, не равный NULL. COALESCE(telegram, phone, 'нет контакта') вернёт телеграм, если он заполнен, иначе телефон, иначе текст. Если NULL все аргументы, результат тоже NULL.

Как переводится coalesce?

С английского coalesce переводят как «сливаться, объединяться». Русская справка Microsoft так и называет статью о функции: «СЛИЯНИЕ (Transact-SQL)». В запросе при этом пишут английское COALESCE.

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

ISNULL принимает ровно два аргумента и возвращает тип первого из них, поэтому длинная строка замены может обрезаться. COALESCE принимает любое число аргументов и берёт тип с наивысшим приоритетом. Ещё ISNULL вычисляется один раз, а аргументы COALESCE могут вычисляться повторно.

Есть ли в PostgreSQL ISNULL, IFNULL или NVL?

Нет, в PostgreSQL для замены NULL используют только COALESCE. Запрос с IFNULL или NVL завершится ошибкой «function does not exist». Запись x ISNULL там есть, но это проверка на NULL, а не замена.

Почему COALESCE вернул пустое значение, хотя запасной вариант заполнен?

Скорее всего, в первом аргументе пустая строка или пробелы. Для COALESCE это обычное значение, поэтому до следующего аргумента очередь не доходит. Помогает связка COALESCE(NULLIF(TRIM(phone), ''), 'не указан').

Что лучше: COALESCE или CASE?

Для замены NULL удобнее COALESCE: запись короче, а SQL Server всё равно переписывает её в CASE. CASE нужен, когда условие сложнее проверки на NULL, например сравнение с порогом или несколько разных правил.

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!