CASE в Oracle SQL — как писать условные выражения

🟢 CASE в Oracle SQL. Введение

CASE в Oracle SQL — это мощный оператор для реализации логики в запросах. Он позволяет возвращать разные значения в зависимости от условий. CASE используется в SELECT, ORDER BY, WHERE и даже в PL/SQL. В этой статье ты найдёшь 50 примеров практического применения CASE.


🖋️ Синтаксис оператора CASE в Oracle

Стандартный формат:

CASE
  WHEN условие1 THEN результат1
  WHEN условие2 THEN результат2
  ELSE результат_по_умолчанию
END

Сравнительный формат:

CASE выражение
  WHEN значение1 THEN результат1
  WHEN значение2 THEN результат2
  ELSE результат_по_умолчанию
END

🔄 Где используется CASE

  • Условная логика в SELECT
  • Динамическое группирование или фильтрация
  • Подстановка значений по условиям
  • Агрегаты с фильтрацией по CASE
  • CASE внутри PL/SQL и процедур

📊 50 примеров использования CASE в Oracle

  1. Простой CASE в SELECT:
SELECT first_name,
  CASE department_id
    WHEN 10 THEN 'Администрация'
    WHEN 20 THEN 'Продажи'
    ELSE 'Другие'
  END AS отдел
FROM employees;
  1. CASE с условиями:
SELECT salary,
  CASE
    WHEN salary > 10000 THEN 'Высокая'
    WHEN salary BETWEEN 5000 AND 10000 THEN 'Средняя'
    ELSE 'Низкая'
  END AS уровень
FROM employees;
  1. CASE в ORDER BY:
SELECT first_name FROM employees
ORDER BY
  CASE department_id
    WHEN 10 THEN 1
    WHEN 20 THEN 2
    ELSE 3
  END;
  1. CASE в WHERE:
SELECT * FROM employees
WHERE
  CASE WHEN job_id = 'IT_PROG' THEN 1 ELSE 0 END = 1;
  1. CASE с NULL:
SELECT first_name,
  CASE
    WHEN commission_pct IS NULL THEN 'Без бонуса'
    ELSE 'С бонусом'
  END AS бонус
FROM employees;
  1. CASE в агрегатной функции:
SELECT
  COUNT(CASE WHEN salary > 10000 THEN 1 END) AS высокие,
  COUNT(CASE WHEN salary <= 10000 THEN 1 END) AS остальные
FROM employees;
  1. CASE с TO_CHAR:
SELECT first_name,
  CASE
    WHEN TO_CHAR(hire_date, 'YYYY') = '2023' THEN 'Новый'
    ELSE 'Старый'
  END AS статус
FROM employees;
  1. CASE в GROUP BY:
SELECT
  CASE WHEN department_id IN (10, 20) THEN 'Управление' ELSE 'Прочее' END AS категория,
  COUNT(*)
FROM employees
GROUP BY CASE WHEN department_id IN (10, 20) THEN 'Управление' ELSE 'Прочее' END;
  1. CASE внутри CASE:
SELECT salary,
  CASE
    WHEN salary > 10000 THEN 'Высокая'
    WHEN salary > 5000 THEN
      CASE
        WHEN department_id = 60 THEN 'Средняя в отделе 60'
        ELSE 'Средняя'
      END
    ELSE 'Низкая'
  END AS уровень
FROM employees;
  1. CASE с NULLIF:
SELECT NULLIF(department_id, 10) AS проверка,
  CASE WHEN NULLIF(department_id, 10) IS NULL THEN 'Совпадает' ELSE 'Различается' END
FROM employees;
  1. CASE и LENGTH:
SELECT first_name,
  CASE
    WHEN LENGTH(first_name) <= 4 THEN 'Короткое имя'
    ELSE 'Длинное имя'
  END AS длина
FROM employees;
  1. CASE в JSON_VALUE:
SELECT
  CASE JSON_VALUE(data, '$.region')
    WHEN 'EU' THEN 'Европа'
    WHEN 'US' THEN 'Америка'
    ELSE 'Другое'
  END AS континент
FROM employees_json;
  1. CASE в подзапросе:
SELECT * FROM employees
WHERE department_id = (
  SELECT CASE WHEN location_id = 1700 THEN 10 ELSE 20 END FROM departments WHERE department_name = 'Sales'
);
  1. CASE с аналитикой:
SELECT first_name,
  CASE WHEN RANK() OVER (ORDER BY salary DESC) <= 3 THEN 'Топ-3' ELSE 'Остальные' END AS категория
FROM employees;
  1. CASE с BETWEEN:
SELECT salary,
  CASE
    WHEN salary BETWEEN 0 AND 3000 THEN 'Низкая'
    WHEN salary BETWEEN 3001 AND 7000 THEN 'Средняя'
    ELSE 'Высокая'
  END AS уровень
FROM employees;
  1. CASE в UPDATE:
UPDATE employees SET bonus =
  CASE
    WHEN department_id = 80 THEN 500
    ELSE 100
  END;
  1. CASE в DELETE:
DELETE FROM employees
WHERE
  CASE WHEN department_id = 50 THEN 1 ELSE 0 END = 1;
  1. CASE в MERGE:
MERGE INTO employees e USING dual d
ON (e.employee_id IS NOT NULL)
WHEN MATCHED THEN UPDATE SET bonus =
  CASE
    WHEN department_id = 10 THEN 300
    ELSE 100
  END;
  1. CASE с INITCAP:
SELECT INITCAP(first_name),
  CASE WHEN INITCAP(first_name) LIKE 'A%' THEN 'A-группа' ELSE 'Другое' END
FROM employees;
  1. CASE с ROWNUM:
SELECT * FROM (
  SELECT e.*, ROWNUM AS rnum FROM employees e
)
WHERE
  CASE WHEN rnum <= 5 THEN 1 ELSE 0 END = 1;
  1. CASE с TO_DATE:
SELECT first_name,
  CASE
    WHEN hire_date < TO_DATE('2020-01-01','YYYY-MM-DD') THEN 'Старый'
    ELSE 'Недавний'
  END AS стаж
FROM employees;
  1. CASE и MOD:
SELECT employee_id,
  CASE MOD(employee_id, 2)
    WHEN 0 THEN 'Чётный'
    ELSE 'Нечётный'
  END AS чётность
FROM employees;
  1. CASE с COALESCE:
SELECT first_name,
  CASE WHEN COALESCE(commission_pct, 0) > 0 THEN 'Есть бонус' ELSE 'Нет бонуса' END
FROM employees;
  1. CASE и NVL2:
SELECT NVL2(commission_pct, 'Бонус', 'Без бонуса') AS статус,
  CASE WHEN NVL2(commission_pct, 1, 0) = 1 THEN 'Да' ELSE 'Нет' END
FROM employees;
  1. CASE с JSON_TABLE:
SELECT * FROM JSON_TABLE(
  '{"employees": [{"id":1,"region":"EU"},{"id":2,"region":"US"}]}'
  , '$.employees[*]'
  COLUMNS (id NUMBER PATH '$.id', region VARCHAR2(10) PATH '$.region')
) WHERE
  CASE region WHEN 'EU' THEN 1 ELSE 0 END = 1;
  1. CASE с аналитикой NTILE:
SELECT first_name,
  CASE NTILE(3) OVER (ORDER BY salary DESC)
    WHEN 1 THEN 'Высший'
    WHEN 2 THEN 'Средний'
    ELSE 'Нижний'
  END AS сегмент
FROM employees;
  1. CASE в RANK PARTITION:
SELECT *,
  CASE WHEN RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) = 1 THEN 'Топ в отделе' ELSE NULL END AS лидер
FROM employees;
  1. CASE и EXTRACT:
SELECT first_name,
  CASE EXTRACT(MONTH FROM hire_date)
    WHEN 1 THEN 'Январь'
    WHEN 12 THEN 'Декабрь'
    ELSE 'Другой месяц'
  END AS месяц_приёма
FROM employees;
  1. CASE в DUMP:
SELECT job_id,
  CASE WHEN DUMP(job_id) LIKE '%73%' THEN 'Содержит 73' ELSE 'Нет' END AS проверка
FROM employees;
  1. CASE с JOIN:
SELECT e.first_name,
  CASE
    WHEN d.department_name LIKE 'S%' THEN 'Отдел S'
    ELSE 'Прочее'
  END AS тип_отдела
FROM employees e
JOIN departments d ON e.department_id = d.department_id;
  1. CASE и LIKE:
SELECT email,
  CASE WHEN email LIKE '%@oracle.com' THEN 'Корпоративный' ELSE 'Внешний' END AS тип
FROM employees;
  1. CASE и SUBSTR:
SELECT SUBSTR(first_name, 1, 1) AS первая_буква,
  CASE SUBSTR(first_name, 1, 1)
    WHEN 'A' THEN 'Группа A'
    ELSE 'Другое'
  END AS группа
FROM employees;
  1. CASE и REGEXP_LIKE:
SELECT first_name,
  CASE
    WHEN REGEXP_LIKE(first_name, '^[A-Z]') THEN 'Заглавная'
    ELSE 'Другое'
  END AS стиль
FROM employees;
  1. CASE и NULL в агрегатах:
SELECT
  CASE WHEN COUNT(commission_pct) = 0 THEN 'Нет данных' ELSE 'Есть' END AS статус
FROM employees;
  1. CASE и FILTER:
SELECT
  COUNT(*) FILTER (WHERE salary > 5000) AS высокие,
  CASE WHEN COUNT(*) FILTER (WHERE salary > 5000) > 10 THEN 'Много' ELSE 'Мало' END AS оценка
FROM employees;
  1. CASE и PERCENTILE_CONT:
SELECT
  PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) AS медиана,
  CASE WHEN salary >= PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY salary) THEN 'Выше медианы' ELSE 'Ниже' END AS позиция
FROM employees;
  1. CASE и SYS_CONTEXT:
SELECT SYS_CONTEXT('USERENV','SESSION_USER') AS пользователь,
  CASE WHEN SYS_CONTEXT('USERENV','SESSION_USER') = 'HR' THEN 'Админ' ELSE 'Пользователь' END AS роль
FROM dual;
  1. CASE и EXPLAIN PLAN:
EXPLAIN PLAN FOR
SELECT * FROM employees
WHERE CASE WHEN department_id = 50 THEN 1 ELSE 0 END = 1;
  1. CASE и CONNECT BY:
SELECT employee_id,
  CASE WHEN LEVEL = 1 THEN 'Корень' ELSE 'Подчинённый' END AS иерархия
FROM employees
CONNECT BY PRIOR employee_id = manager_id;
  1. CASE и JSON_EXISTS:
SELECT * FROM employees_json
WHERE CASE WHEN JSON_EXISTS(data, '$.bonus') THEN 1 ELSE 0 END = 1;
  1. CASE в SELECT без таблицы:
SELECT CASE WHEN 1 = 1 THEN 'Истина' ELSE 'Ложь' END FROM dual;
  1. CASE с SIGN:
SELECT salary,
  CASE SIGN(salary - 5000)
    WHEN -1 THEN 'Меньше'
    WHEN 0 THEN 'Равно'
    WHEN 1 THEN 'Больше'
  END AS сравнение
FROM employees;
  1. CASE и GREATEST:
SELECT GREATEST(salary, bonus) AS максимум,
  CASE
    WHEN GREATEST(salary, bonus) = salary THEN 'Оклад выше'
    ELSE 'Бонус выше'
  END AS итог
FROM employees;
  1. CASE и IN:
SELECT job_id,
  CASE
    WHEN job_id IN ('IT_PROG', 'SA_MAN') THEN 'Технический'
    ELSE 'Другой'
  END AS категория
FROM employees;
  1. CASE и SIGN + ABS:
SELECT salary,
  CASE SIGN(ABS(salary - 5000))
    WHEN 0 THEN 'Ровно 5000'
    ELSE 'Отклонение'
  END AS статус
FROM employees;

📆 Заключение: зачем использовать CASE

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

Освоив CASE, ты сможешь создавать универсальные запросы, обрабатывать данные по условиям и делать отчёты более наглядными. Обязательно к освоению для бизнес-аналитиков и SQL-разработчиков.


🕸️ Следующая статья:

BODY в Oracle SQL — как описывать реализацию пакетов, процедур и функций


 

Понравилась статья? Поделиться с друзьями:
5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии