CASE выражения: условная логика внутри SQL-запроса
Введение в CASE выражения: ваш SQL-запрос становится умнее! 🧠
SQL — это не просто язык для извлечения данных, а мощный инструмент для их преобразования. С помощью CASE вы можете внести условную логику прямо в запрос, делая его гибким и адаптивным.
Представьте: вы анализируете продажи и хотите классифицировать клиентов по уровню трат, или вам нужно преобразовать числовые статусы заказов в понятные текстовые метки. Вот где CASE становится вашим лучшим помощником!
Синтаксис CASE: два варианта на выбор
В SQL есть две формы выражения CASE:
- Простая форма — проверяет точные совпадения (как
switchв других языках). - Поисковая форма — позволяет задавать сложные условия (аналог
if-else).
Простая форма: CASE WHEN x THEN y
SELECT
product_name,
price,
CASE price_category
WHEN 'budget' THEN 'Доступный'
WHEN 'premium' THEN 'Премиум'
ELSE 'Стандартный'
END AS price_label
FROM products;
Что происходит?
- Если price_category равен 'budget', то вернётся 'Доступный'.
- Если 'premium' — 'Премиум'.
- Во всех остальных случаях — 'Стандартный'.
Поисковая форма: CASE WHEN условие THEN результат
SELECT
order_id,
total_amount,
CASE
WHEN total_amount > 1000 THEN 'Крупный заказ'
WHEN total_amount BETWEEN 500 AND 1000 THEN 'Средний заказ'
ELSE 'Мелкий заказ'
END AS order_size
FROM orders;
Ключевое отличие:
- Здесь условия могут быть любыми (>, <, LIKE, IN и т. д.).
- Порядок условий важен! SQL использует первое совпавшее.
Где можно применять CASE?
1. В SELECT — создание вычисляемых полей
SELECT
customer_name,
CASE
WHEN last_purchase_date > CURRENT_DATE - INTERVAL '30 days' THEN 'Активный'
ELSE 'Неактивный'
END AS customer_status
FROM customers;
2. В ORDER BY — гибкая сортировка
SELECT
product_name,
stock_quantity
FROM products
ORDER BY
CASE
WHEN stock_quantity < 10 THEN 0 -- Сначала товары с низким запасом
ELSE 1
END;
3. В GROUP BY и агрегатных функциях
SELECT
CASE
WHEN age < 18 THEN 'До 18'
WHEN age BETWEEN 18 AND 30 THEN '18-30'
ELSE '30+'
END AS age_group,
COUNT(*) AS user_count
FROM users
GROUP BY age_group;
Продвинутые примеры
Вложенные CASE
SELECT
product_id,
CASE
WHEN discontinued = 1 THEN 'Снят с производства'
WHEN stock_quantity = 0 THEN 'Нет в наличии'
ELSE
CASE
WHEN price < 50 THEN 'Дешёвый'
ELSE 'Дорогой'
END
END AS product_status
FROM products;
CASE с агрегатами
SELECT
COUNT(*) AS total_orders,
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed_orders,
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) AS cancelled_orders
FROM orders;
Ошибки, которых стоит избегать
- Не забывайте про
ELSE— если его нет, непредусмотренные случаи вернутNULL. - Порядок условий важен — SQL выполняет первое совпадение.
- Не усложняйте без нужды — иногда лучше вынести логику в приложение.
Закрепим на практике!
Попробуйте решить задачу:
-- Напишите запрос, который классифицирует сотрудников по стажу:
-- * Менее 1 года: "Новичок"
-- * 1-3 года: "Опытный"
-- * Более 3 лет: "Ветеран"
SELECT
employee_name,
hire_date,
CASE
WHEN hire_date > CURRENT_DATE - INTERVAL '1 year' THEN 'Новичок'
WHEN hire_date > CURRENT_DATE - INTERVAL '3 years' THEN 'Опытный'
ELSE 'Ветеран'
END AS experience_level
FROM employees;
Теперь ваши SQL-запросы стали ещё мощнее! 💪