В этом руководстве мы разберем одну из самых полезных конструкций в SQL — CASE WHEN THEN. Она позволяет добавлять в запросы логику: проверять условия, классифицировать данные и выводить разные результаты в зависимости от значений. Все примеры основаны на реальных таблицах products (товары) и categories (категории).
Структура данных
Для понимания примеров, взглянем на наши таблицы:
-
products — товары:
product_name(название),price(цена),category(ссылка на категорию),tags(массив тегов). -
categories — категории:
categori_id(ID),categori_name(название),parent_id(ссылка на родительскую категорию).
1. Простая категоризация: ценовые сегменты
Самая частая задача — разбить товары на группы по какому-либо признаку. Например, создать ценовые сегменты: дешевый, средний, дорогой, премиум.
SELECT product_name, price, CASE WHEN price < 1000 THEN 'Дешевый' WHEN price BETWEEN 1000 AND 10000 THEN 'Средний' WHEN price BETWEEN 10001 AND 50000 THEN 'Дорогой' WHEN price > 50000 THEN 'Премиум' ELSE 'Не указана' END AS price_category FROM products ORDER BY price;
Как это работает:
Конструкция CASE последовательно проверяет условия сверху вниз. Как только условие выполняется (WHEN ... THEN), возвращается указанный результат, и остальные условия не проверяются. ELSE срабатывает, если ни одно условие не подошло.
2. Логика со связями: определяем электронику
У нас есть иерархические категории. Допустим, категория «Электроника» имеет id = 1. Все товары, которые лежат либо прямо в этой категории, либо в её подкатегориях (где parent_id = 1), мы хотим пометить как «Электроника».
SELECT p.product_name, c.categori_name, CASE WHEN c.parent_id = 1 OR c.categori_id = 1 THEN 'Электроника' ELSE 'Не электроника' END AS is_electronics FROM products p JOIN categories c ON p.category = c.categori_id;
Здесь CASE помогает объединить логику через OR прямо внутри запроса, проверяя поля связанной таблицы.
3. Работа с массивами: популярность по тегам
В колонке tags хранятся массивы строк (например, {новинка,хит,подарок}). Мы можем оценить популярность товара по количеству этих тегов.
SELECT product_name, tags, CASE WHEN array_length(tags, 1) IS NULL THEN 'Нет тегов' WHEN array_length(tags, 1) = 1 THEN 'Мало тегов' WHEN array_length(tags, 1) BETWEEN 2 AND 3 THEN 'Средняя популярность' WHEN array_length(tags, 1) >= 4 THEN 'Высокая популярность' END AS popularity_level FROM products;
Функция array_length(tags, 1) возвращает количество элементов в массиве. CASE позволяет на основе этого числа присвоить товару понятный текстовый статус.
4. Продвинутый уровень: подзапросы внутри CASE
Самое интересное — использовать внутри CASE подзапросы. Например, мы хотим сравнить каждый товар с глобальными показателями по всему магазину (самый дорогой, самый дешевый, выше/ниже среднего).
SELECT product_name, price, CASE WHEN price = (SELECT MAX(price) FROM products) THEN 'Самый дорогой товар' WHEN price = (SELECT MIN(price) FROM products) THEN 'Самый дешевый товар' WHEN price > (SELECT AVG(price) FROM products) THEN 'Выше среднего по магазину' ELSE 'Ниже или равно среднему по магазину' END AS global_price_status FROM products;
Важный момент: Подзапросы в круглых скобках выполняются для каждой строки? В данном случае — нет. Современные СУБД (включая PostgreSQL) оптимизируют такие запросы: MAX, MIN, AVG вычисляются один раз для всей таблицы, что делает этот подход эффективным и наглядным.
Итог
Конструкция CASE WHEN THEN превращает SQL из просто языка выборки в язык с логикой. С её помощью вы можете:
-
Создавать произвольные категории на основе полей.
-
Реализовывать ветвления логики с проверкой нескольких условий.
-
Использовать результаты подзапросов для гибкого сравнения.
-
Работать с массивами и другими типами данных.
Практикуйтесь, комбинируйте условия и пишите сложные, но понятные запросы
Статья подготовлена по материалам обучающего видео для вашего удобства.