CASE
Условная логика внутри SQL-запроса
Теория
Существует интересная конструкция, ее еще часто называют условной, называется она CASE. Она позволяет добавить в запрос условную логику: если для строки выполняется одно условие — вернуть одно значение, если другое — вернуть другое.
Можно думать о CASE как о маленьком наборе правил прямо внутри запроса. SQL берёт строку, проверяет её по этим правилам и возвращает результат, который вы хотите получить, если для строки правило выполняется.
Важно: CASE ничего не меняет в таблице, а только показывает данные в более удобном виде в результате SELECT или помогает задать свою логику сортировки в ORDER BY или выполняет гибкие вычисления.
Синтаксис
CASE
WHEN condition THEN result
WHEN condition THEN result
ELSE result
END
SQL
• после WHEN пишется условие, которое нужно проверить;
• после THEN пишется значение, которое нужно получить, если условие выполнилось;
• ELSE — это запасной вариант на случай, если ни одно условие выше не выполнилось.
CASE проверяет условия сверху вниз. Как только для текущей строки подошло первое условие, SQL сразу берёт значение из этого THEN и дальше уже не идёт.
Поэтому порядок веток очень важен. Сначала обычно ставят более точные или более приоритетные условия, а потом уже всё остальное. Или условие четко определяют нижней и верхней границей через AND.
Если ELSE не написать, то для строк, которые не попали ни под одно условие, результатом будет NULL. Иногда это нормально, но чаще удобнее сразу явно указать, что вернуть по умолчанию.
Важно: весь CASE ... END можно назвать через псевдоним так же, как обычный вычисляемый столбец. Именно поэтому в примерах ниже после END стоит AS new_salary, AS city_label или AS status_label.
Примеры
1. Считаем новую зарплату по разным правилам повышения
🔄 Попробуйте изменить запрос:
- • Поменяйте границу 70000 на 80000 и посмотрите, кому теперь попадёт повышение 20%
- • Сделайте повышение для средней группы не на 10%, а на 15%: salary * 1.15
2. Показываем вместо пустого города понятный текст
🔄 Попробуйте изменить запрос:
- • Замените текст 'город не указан' на 'нет данных'
- • Отсортируйте результат по вычисляемому столбцу: ORDER BY city_label ASC
3. Расшифровываем статусы заказов в более человеческий вид
🔄 Попробуйте изменить запрос:
- • Сделайте для 'доставлен' отдельную подпись, убрав его из IN
- • Поменяйте текст 'Статус не указан' на 'Ожидает обработки'
4. Сортируем пользователей по своему правилу
🔄 Попробуйте изменить запрос:
- • Поставьте строки без города в начало, изменив число у ветки WHEN city IS NULL
- • Поменяйте местами приоритеты для 'Москва' и 'Алматы'
Типичные ошибки
Ставят условия в неудачном порядке
CASE идёт сверху вниз. Если верхнее условие уже подходит строке, остальные условия ниже для этой строки уже не проверяются. Поэтому сначала лучше ставить более точные условия, а потом более общие.
Забывают про ELSE
Если ни одно условие не подошло, а ELSE нет, результатом будет NULL. Иногда это нормально, но чаще пользователь просто увидит пустое значение и не поймёт, почему так произошло. Вместо ELSE можно также указать еще одну ветку THEN, в которой указать все остальные случаи.
Пытаются обрабатывать NULL как обычное значение
Если нужно отдельно поймать пустое значение, надёжнее писать WHEN column IS NULL THEN .... Это понятнее и работает предсказуемо.
Думают, что CASE меняет данные в таблице
Нет, не меняет. Он только вычисляет значение в результате запроса. В самой таблице ничего не переписывается.
Практика
Проверь себя
Ответьте на вопросы, чтобы закрепить материал:
CASE WHEN price >= 50000 THEN 'дорогой' WHEN price >= 100000 THEN 'премиум' ELSE 'обычный' END