Условные выражения в запросах
CASE WHEN - часто используемое условное выражение в запросах. Его особенности и факты далее.
А пока подписывайся на мой канал На связи: SQL Там я публикую посты про особенности и нюансы SQL. Этот канал про то, как не бояться баз данных, понимать, что такое JOIN, GROUP BY и почему NULL ≠ 0. Его я веду с нуля подписчиков. Присоединяйся!
CASE - возвращает значение, но не управляет логикой выполнения запроса.
SELECT
name,
CASE
WHEN salary > 100000 THEN 'богач'
WHEN salary BETWEEN 50000 AND 100000 THEN 'норм'
ELSE 'бедняк'
END AS category
FROM employees;
Здесь CASE не «делает выборку», а вычисляет новое значение для каждой строки.
Где используется CASE
✅ В SELECT - чтобы выводить вычисленные поля
✅ В WHERE - чтобы сделать фильтрацию условной
✅ В ORDER BY - чтобы сортировать по кастомной логике
✅ В GROUP BY и HAVING - для агрегатов с условиями
Пример в ORDER BY:
ORDER BY
CASE WHEN status = 'vip' THEN 1 ELSE 2 END
В итоге VIP-клиенты окажутся первыми — без лишнего UNION или сортировки по тексту.
Где нельзя использовать CASE
Нельзя динамически подменять им названия колонок или таблиц — SQL так не работает:
SELECT * FROM CASE WHEN ... THEN table1 ELSE table2 END -- ошибка
Нельзя изменять структуру запроса — CASE не может выбирать, какие поля попадут в SELECT.
То есть он работает только на уровне данных, не на уровне схемы запроса.
Неочевидные факты
1. CASE возвращает первое совпадение
SQL идёт сверху вниз — как только условие совпало, остальные даже не проверяются.
Поэтому важно порядок условий.
CASE
WHEN score > 80 THEN 'A'
WHEN score > 90 THEN 'A+' -- никогда не сработает
END
Потому что >80 ловит всё, включая >90.
2. Тип результата — общий для всех веток
CASE пытается привести все результаты к единому типу.
Если ты вернёшь 'текст' и NULL, всё ок.
Но если 'текст' и 123, то SQL может выдать ошибку или привести число к строке.
💡 Всегда делай значения одного типа, особенно если потом используешь CASE в арифметике.
3. Есть две формы: сравнительная и поисковая
Обычно используют поисковую:
CASE WHEN condition THEN result ... END
Но есть ещё сравнительная:
CASE status
WHEN 'new' THEN 1
WHEN 'active' THEN 2
END
Она короче, но менее гибкая — работает только с равенством (=).
4. CASE + агрегаты = мощный аналитический трюк
Чтобы посчитать агрегаты по категориям в одной строке:
SELECT
SUM(CASE WHEN gender = 'M' THEN 1 ELSE 0 END) AS male_count,
SUM(CASE WHEN gender = 'F' THEN 1 ELSE 0 END) AS female_count
FROM users;
Один запрос, два счётчика, без подзапросов и джойнов.
5. CASE в WHERE — не всегда оптимален
Когда ты используешь CASE в WHERE, PostgreSQL часто не может применить индекс,
потому что условие становится непредсказуемым.
Пример:
WHERE
CASE WHEN is_vip THEN discount > 10 ELSE discount > 30 END
Лучше выносить логику в OR:
WHERE (is_vip AND discount > 10)
OR (NOT is_vip AND discount > 30)
Так планировщик сможет использовать индексы (их наличие подразумевается)
Где CASE особенно полезен
Когда нужно сделать динамическую сегментацию данных (категории, статусы, группы)
При построении витрин и отчётов (разделить аудиторию, выделить группы риска и т.п.)
Для чистки данных на лету (заменить NULL на текст или дефолтное значение)
В AB-тестах — присвоить группе метку на основании условия
Если тебе нравятся такие разборы SQL с реальными примерами и подводными камнями —
подписывайся на мой Telegram На связи: SQL







