CodeRang
Темы SQL

CASE SQL: как работает CASE WHEN

CASE SQL позволяет вернуть разное значение в зависимости от условия прямо внутри запроса. Разберём CASE WHEN SQL на примере классификации данных, условной агрегации, нескольких WHEN и ветки ELSE.

Обновлено · Команда SQL Arena

Что потренируете

  • Строить категории через CASE WHEN
  • Использовать CASE внутри SUM и других агрегатов
  • Правильно располагать условия от более строгих к общим
  • Учитывать ELSE и возможный NULL
  • Применять CASE для сортировки и флагов

Пример задачи в тренажёре

Так выглядит задача в SQL Arena: условие, редактор, результат и схема базы.

Пред.След.Случайная
ЗаданиеОтправкиAI Mentor
Разделить клиентов по сумме оплаченных заказов

Для каждого клиента посчитайте сумму только заказов со статусом paid. Верните customer_name, paid_total и spend_group: high для суммы от 500, medium для суммы от 200 до 499.99, low для остальных. Отсортируйте результат по paid_total по убыванию, затем по имени.

Запрос 1PostgreSQLv16
SELECT c.customer_name,
       SUM(CASE WHEN o.status = 'paid' THEN o.amount ELSE 0 END) AS paid_total,
       CASE WHEN SUM(CASE WHEN o.status = 'paid' THEN o.amount ELSE 0 END) >= 500 THEN 'high'
            WHEN SUM(CASE WHEN o.status = 'paid' THEN o.amount ELSE 0 END) >= 200 THEN 'medium'
            ELSE 'low' END AS spend_group
FROM customers c JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.customer_name
ORDER BY paid_total DESC, c.customer_name;
Отправить
Результатcustomersorders
Ответ принят

Как работает CASE WHEN в SQL

Первый CASE находится внутри SUM. Выражение проверяет статус каждой строки orders. Для paid оно возвращает amount, для остальных статусов — 0. Поэтому возврат, ожидающий и отменённый заказ не увеличивают paid_total. Это распространённый приём условной агрегации: вместо отдельного запроса для нужного статуса условие помещается прямо внутрь агрегатной функции.

Второй CASE выполняется уже над итоговой суммой клиента. Сначала проверяется порог 500, затем 200. Порядок важен: CASE останавливается на первой истинной ветке. Если сначала написать WHEN paid_total >= 200, клиент с суммой 700 тоже попадёт в эту ветку и получит medium. Поэтому диапазоны обычно проверяют от более строгого условия к более широкому.

ELSE задаёт результат для всех строк, которые не подошли под предыдущие WHEN. Здесь это low, включая Eva: у неё есть заказ, но он отменён, поэтому условная сумма равна нулю. Завершающий ORDER BY делает результат стабильным. CASE также можно использовать прямо в ORDER BY, например если нужно вручную поставить high перед medium и low независимо от суммы.

CASE проверяет условия сверху вниз и возвращает результат первой подходящей ветки WHEN. Поэтому порядок условий особенно важен, когда диапазоны пересекаются: более строгое условие обычно ставят раньше общего. ELSE определяет результат для строк, которые не подошли ни под один WHEN; если ELSE отсутствует, CASE вернёт NULL. Выражение CASE можно использовать в SELECT, ORDER BY, агрегатных выражениях и других частях запроса, где допустимо вычисляемое значение. Конструкция также часто применяется для условной агрегации, например SUM(CASE WHEN condition THEN amount ELSE 0 END).

SQLPostgreSQL v16
SELECT c.customer_name,
       SUM(CASE WHEN o.status = 'paid' THEN o.amount ELSE 0 END) AS paid_total,
       CASE WHEN SUM(CASE WHEN o.status = 'paid' THEN o.amount ELSE 0 END) >= 500 THEN 'high'
            WHEN SUM(CASE WHEN o.status = 'paid' THEN o.amount ELSE 0 END) >= 200 THEN 'medium'
            ELSE 'low' END AS spend_group
FROM customers c JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.customer_name
ORDER BY paid_total DESC, c.customer_name;
Результат запроса
customer_namepaid_totalspend_group
David700.00high
Anna540.00high
Boris240.00medium
Clara90.00low
Eva0low

Типичные ошибки в CASE SQL

01

Слишком широкая ветка стоит первой

Условие WHEN total >= 200 перед WHEN total >= 500 перехватит обе группы. Вторая ветка для high никогда не выполнится. Проверяйте пересечения диапазонов и ставьте более специфичные условия раньше.

02

В условной сумме забыли ELSE 0

CASE без ELSE возвращает NULL, если ни один WHEN не подошёл. SUM обычно проигнорирует такие NULL, поэтому конкретный запрос может выглядеть рабочим, но выражение становится менее явным и в других вычислениях способно дать неожиданный NULL.

03

CASE считают заменой фильтрации

CASE меняет возвращаемое значение, но сам по себе не удаляет строки. Если задача требует полностью исключить записи, нужен WHERE или подходящее условие соединения. В этой задаче строки сохраняются специально, а ненужные статусы дают ноль внутри SUM.

Задачи по теме в тренажёре

Курс «SQL с нуля»

После примера можно перейти к CASE в SQL задачах с разными формами условной логики. В бесплатных задачах есть простая проверка наличия Wi-Fi в каютах и изменение кодировки значений, а в более сложных — ценовые категории витрины «Котомаркета» и статус-метки заказов. Так можно отдельно потренировать флаги, несколько WHEN и CASE над числовыми и текстовыми значениями. В SQL Arena доступно 1 192 задачи для PostgreSQL, MySQL, ClickHouse и BigQuery. В каждой задаче свои таблицы, а решение проверяется на скрытых данных, поэтому недостаточно подогнать запрос под строки из примера. Бесплатный тариф без карты включает 292 задачи на всех четырёх диалектах. Если CASE пока смешивается с базовым SELECT, фильтрацией и агрегатами, продолжить можно в курсе «SQL с нуля»: теория там сопровождается задачей в каждом уроке, а первые главы доступны бесплатно.

Частые вопросы

Что такое CASE SQL?

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

Как работает CASE WHEN SQL?

Условия WHEN проверяются по порядку сверху вниз. Как только найдено первое истинное условие, CASE возвращает соответствующий результат и остальные ветки уже не проверяет.

Обязательно ли писать ELSE в CASE WHEN?

Нет, ELSE необязателен. Если ни один WHEN не сработал и ELSE отсутствует, результатом выражения будет NULL.

Можно ли использовать CASE WHEN внутри SUM?

Да. Конструкция SUM(CASE WHEN условие THEN значение ELSE 0 END) часто используется для условной агрегации, когда нужно суммировать только строки, отвечающие определённому условию.

Можно ли написать несколько WHEN в CASE SQL?

Да, CASE может содержать несколько веток WHEN. Их порядок имеет значение, потому что возвращается результат первой ветки с истинным условием.

Практика запросов с CASE WHEN SQL

В SQL Arena можно решать задачи на CASE в браузере и сразу получать результат проверки. Скрытые данные помогают проверить, работает ли логика запроса за пределами показанного примера. Для разбора ошибки можно использовать AI-ментора, а схемы таблиц смотреть на ER-диаграммах.

Перейти к задачам по CASE