JavaRush /Курсы /SQL SELF /Условные выражения: CASE <выражение> WHEN .....

Условные выражения: CASE <выражение> WHEN ... THEN ... ELSE ... END

SQL SELF
10 уровень , 1 лекция
Открыта

Если вы уже знакомы с CASE, способом встраивать логику прямо в запрос. Но не все знают, что у CASE есть две формы. Если CASE WHEN ... — это проверка условий типа if-else, то простой CASE — это как switch-case из других языков: он сравнивает одно выражение с несколькими значениями и выполняет соответствующий блок.

Он выглядит компактнее и интуитивнее, когда вы сравниваете одно поле с фиксированными значениями.

Синтаксис простого CASE

CASE expression
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ...
    ELSE default_result
END

Всё просто:

  • expression — это выражение или поле, которое сравнивается со значениями value1, value2 и т.д.
  • THEN указывает, что вернуть при совпадении.
  • ELSE — что вернуть, если ничего не подошло (можно опустить, но лучше не надо).

Пример: Оценки студентов

Представим таблицу students со столбцом grade, содержащим целое число от 2 до 5. Мы хотим отобразить текстовую интерпретацию оценок.

SELECT
    name,
    grade,
    CASE grade
        WHEN 5 THEN 'Отлично'
        WHEN 4 THEN 'Хорошо'
        WHEN 3 THEN 'Удовлетворительно'
        WHEN 2 THEN 'Неудовлетворительно'
        ELSE 'Неизвестно'
    END AS оценка_словами
FROM students;

Здесь CASE сравнивает значение поля grade с фиксированными значениями 2, 3, 4, 5.

Пример: Категории товаров по коду

В таблице products есть поле category_code, в котором лежат короткие метки: 'el', 'frn', 'bks' и т. д. Мы хотим отобразить читаемое название категории.

SELECT
    product_name,
    category_code,
    CASE category_code
        WHEN 'el' THEN 'Электроника'
        WHEN 'frn' THEN 'Мебель'
        WHEN 'bks' THEN 'Книги'
        ELSE 'Прочее'
    END AS category_name
FROM products;

Этот приём особенно удобен, когда нужно отображать "человеческий" текст вместо кода.

Пример: Названия месяцев

Иногда хочется отобразить названия месяцев в виде текста по номеру:

SELECT
    EXTRACT(MONTH FROM order_date) AS month_number,
    CASE EXTRACT(MONTH FROM order_date)
        WHEN 1 THEN 'Январь'
        WHEN 2 THEN 'Февраль'
        WHEN 3 THEN 'Март'
        WHEN 4 THEN 'Апрель'
        WHEN 5 THEN 'Май'
        WHEN 6 THEN 'Июнь'
        WHEN 7 THEN 'Июль'
        WHEN 8 THEN 'Август'
        WHEN 9 THEN 'Сентябрь'
        WHEN 10 THEN 'Октябрь'
        WHEN 11 THEN 'Ноябрь'
        WHEN 12 THEN 'Декабрь'
        ELSE 'Неизвестно'
    END AS month_name
FROM orders;

Здесь простое CASE делает понятным то, что иначе выглядело бы как числа от 1 до 12.

Работа с NULL в простом CASE

Важно понимать, что если значение сравнивается с NULL, то результат будет NULL, потому что NULL = NULL — это не истина, а неизвестно.

Пример с NULL:

SELECT
    user_id,
    status,
    CASE status
        WHEN 'active' THEN 'Активен'
        WHEN 'blocked' THEN 'Заблокирован'
        WHEN NULL THEN 'Нет статуса'  -- не сработает!
        ELSE 'Неизвестно'
    END AS user_state
FROM users;

Вместо WHEN NULL следует использовать ELSE, или просто применить поисковый CASE (который мы разбирали в прошлой лекции):

CASE
    WHEN status IS NULL THEN 'Нет статуса'
    ...

Сравнение с поисковым CASE

Особенность Простой CASE Поисковый CASE
Сравнение с конкретными значениями ✅ Удобен ❌ Не подходит
Гибкость условий (>, IS NULL) ❌ Нельзя ✅ Можно
Аналог в программировании switch-case if-else

Практические кейсы

Пример: Визуализация статуса заявки

request_id status
101 new
102 in_progress
103 done
104 cancelled
105 NULL
SELECT
    request_id,
    CASE status
        WHEN 'new' THEN '🟡 Новая'
        WHEN 'in_progress' THEN '🔵 В работе'
        WHEN 'done' THEN '🟢 Завершена'
        ELSE '⚪ Неизвестно'
    END AS status_label
FROM requests;
request_id status_label
101 🟡 Новая
102 🔵 В работе
103 🟢 Завершена
104 ⚪ Неизвестно
105 ⚪ Неизвестно

Здесь CASE действует как переводчик: превращает технические статусы в понятные (и даже симпатичные) метки. И если статус неизвестен или NULL — пользователь получит ⚪ «Неизвестно».

Пример: Группировка по категориям для отчёта

employee_id name department
1 Alex Lin HR
2 Maria Chi IT
3 Anna Song IT
4 Otto Art FIN
5 Jane Doe HR
6 Max Gray SALES
7 Zoe Black IT
8 Tom Brown FIN
9 Liam Park NULL
10 Eva Gold HR
SELECT
    CASE department
        WHEN 'HR' THEN 'Кадры'
        WHEN 'IT' THEN 'Технологии'
        WHEN 'FIN' THEN 'Финансы'
        ELSE 'Прочее'
    END AS dept_name,
    COUNT(*) AS staff_count
FROM employees
GROUP BY
    CASE department
        WHEN 'HR' THEN 'Кадры'
        WHEN 'IT' THEN 'Технологии'
        WHEN 'FIN' THEN 'Финансы'
        ELSE 'Прочее'
    END;

Результат:

dept_name staff_count
Кадры 3
Технологии 3
Финансы 2
Прочее 2

Что здесь происходит:

  • Сотрудники из департамента HR попадают в категорию Кадры.
  • IT — это Технологии.
  • FIN — это Финансы.
  • Всё остальное, включая SALES и NULL, попадает в Прочее. Такой подход отлично подходит для создания дружелюбных и понятных отчетов.

Распространённые ошибки

  • Забыл ELSE → получаешь NULL, если ни одно значение не совпало.
  • Сравниваешь с NULL → не работает, используй IS NULL и поисковый CASE.
  • Сравниваешь несовместимые типы → например, CASE grade WHEN '5' если grade числовой тип .

Простой CASE — это ваш инструмент, когда нужно сравнить одно значение с набором возможных. Он компактен, читаем и особенно полезен для текстовой классификации, визуализации, преобразования кодов и удобного группирования.

Если же вам нужно проверять диапазоны, NULL, или более сложные условия — берите поисковый CASE. SQL любит ясность. А CASE — ваш инструмент, чтобы дать этой ясности форму.

2
Задача
SQL SELF, 10 уровень, 1 лекция
Недоступна
Присвоение текстовых описаний оценкам
Присвоение текстовых описаний оценкам
2
Задача
SQL SELF, 10 уровень, 1 лекция
Недоступна
Сравнение категорий товаров
Сравнение категорий товаров
Комментарии (7)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Анатолий Уровень 27
27 января 2026
❤️
Anemon Уровень 13 Expert
29 августа 2025
🤓
Ra Уровень 35 Student
24 июля 2025
Условие неоднозначное, но для учебной задачи норм. Что если категорий больше чем 3?
Юрий Уровень 60
24 июня 2025
А зачем в примере

SELECT
    CASE department
        WHEN 'HR' THEN 'Кадры'
        WHEN 'IT' THEN 'Технологии'
        WHEN 'FIN' THEN 'Финансы'
        ELSE 'Прочее'
    END AS dept_name,
    COUNT(*) AS staff_count
FROM employees
GROUP BY
    CASE department
        WHEN 'HR' THEN 'Кадры'
        WHEN 'IT' THEN 'Технологии'
        WHEN 'FIN' THEN 'Финансы'
        ELSE 'Прочее'
    END;
в group by case?
Blackskillow Уровень 19
26 июня 2025
Привет, предположу, в group by мы должны указать столбец из select. А раз в select такая огромная партянка, то всю ее и надо указать.
Юрий Уровень 60
27 июня 2025
Я конечно не знаю как MsSql но в постгресе нужно групировать по department и все . это, видимо, ошибка
Евгений Уровень 49 Expert
23 июля 2025
по стандарту SQL GROUP BY выполняется перед SELECT. Соответственно, GROUP BY ничего не знает об алиасах и вычислениях, сделанных на этапе SELECT, поэтому в данном случае приходится дублировать выражение. Но да, конкретно в постгресе это упрощено, там можно сразу алиас использовать прямо в GROUP BY, но не факт, что в других БД так же будет.