Условные выражения CASE WHEN, COALESCE, NULLIF
Условные выражения SQL: CASE WHEN, COALESCE, NULLIF — ветвление внутри запроса без хранимых процедур и обработка NULL.
Условные выражения позволяют принимать решения прямо внутри SQL-запроса: назначать метки, заменять NULL, делить данные на категории.
CASE WHEN — ветвление
Синтаксис похож на if–else: перебираем условия, возвращаем первое истинное:
SELECT
emp_name,
salary,
CASE
WHEN salary >= 8000 THEN 'Senior'
WHEN salary >= 6000 THEN 'Middle'
ELSE 'Junior'
END AS grade
FROM employees
ORDER BY salary DESC;
Результат:
emp_name | salary | grade -------------+--------+------- Sarah Connor | 8000 | Senior Rick Deckard | 7200 | Middle Tony Montana | 6500 | Middle Martin Blank | 5600 | Junior Ethan Hunt | 5000 | Junior
CASE с агрегатами — условный COUNT
Мощный приём: считать строки только при выполнении условия:
-- Сколько сотрудников в каждой грейд-группе
SELECT
CASE
WHEN salary >= 8000 THEN 'Senior'
WHEN salary >= 6000 THEN 'Middle'
ELSE 'Junior'
END AS grade,
COUNT(*) AS cnt
FROM employees
GROUP BY grade
ORDER BY cnt DESC;
Результат:
grade | cnt -------+---- Junior | 2 Middle | 2 Senior | 1
COALESCE — замена NULL
COALESCE(a, b, c, ...) возвращает первый аргумент, который не NULL:
-- Если отдел не назначен — показать 'Unassigned'
SELECT
emp_name,
COALESCE(CAST(dept_id AS TEXT), 'Unassigned') AS department
FROM employees;
Результат:
emp_name | department -------------+----------- Ethan Hunt | 4 Tony Montana | 1 Sarah Connor | 5 Rick Deckard | 3 Martin Blank | Unassigned
COALESCE с двумя столбцами
Полезно, когда значение может быть в одном из нескольких столбцов:
-- Берём city, а если NULL — postal_code
SELECT
cust_name,
COALESCE(city, postal_code, 'Unknown') AS location
FROM customers
LIMIT 4;
Результат:
cust_name | location -----------------+--------- Maria Anders | Berlin Fran Wilson | Madrid Dominique Perrier| Paris Martin Blank | Turin
NULLIF — обратное COALESCE
NULLIF(a, b) возвращает NULL, если a = b, иначе возвращает a. Часто используется, чтобы избежать деления на ноль:
-- Пример: делим salary на dept_id
-- dept_id может быть NULL, а NULLIF защищает от деления на 0
SELECT
emp_name,
salary,
dept_id,
ROUND(salary * 1.0 / NULLIF(dept_id, 0), 1) AS ratio
FROM employees;
Результат:
emp_name | salary | dept_id | ratio -------------+--------+---------+------- Ethan Hunt | 5000 | 4 | 1250.0 Tony Montana | 6500 | 1 | 6500.0 Sarah Connor | 8000 | 5 | 1600.0 Rick Deckard | 7200 | 3 | 2400.0 Martin Blank | 5600 | NULL | NULL
Когда
dept_idравен NULL (или был бы 0),NULLIFвозвращает NULL, и результат деления тоже NULL — вместо ошибки.
Коротко
CASE WHEN ... THEN ... ELSE ... END— ветвление внутри SELECT; работает и в ORDER BY, и внутри агрегатов.COALESCE(a, b)возвращает первый не-NULL аргумент — удобно заменять NULL на значение по умолчанию.NULLIF(a, b)возвращает NULL при равенстве — защита от деления на ноль и «пустых» строк.
Проверьте себя
1. Где в запросе можно использовать CASE WHEN?
AТолько в SELECT
BВ SELECT, ORDER BY и WHERE
CВ SELECT, ORDER BY, WHERE, GROUP BY и HAVING
DТолько во WHERE
2. Что вернёт COALESCE(NULL, NULL, 42, 100)?
ANULL
B42
C100
DОшибку
3. Зачем нужен NULLIF(x, 0) в выражении деления?
AЧтобы заменить 0 на NULL и избежать ошибки деления на ноль
BЧтобы вернуть 0 вместо NULL
CЧтобы проверить, равен ли x нулю
DЧтобы округлить результат деления