이미 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 '1월'
WHEN 2 THEN '2월'
WHEN 3 THEN '3월'
WHEN 4 THEN '4월'
WHEN 5 THEN '5월'
WHEN 6 THEN '6월'
WHEN 7 THEN '7월'
WHEN 8 THEN '8월'
WHEN 9 THEN '9월'
WHEN 10 THEN '10월'
WHEN 11 THEN '11월'
WHEN 12 THEN '12월'
ELSE '알 수 없음'
END AS month_name
FROM orders;
이렇게 간단한 CASE로 숫자(1~12)를 바로 월 이름으로 바꿔줄 수 있어.
간단한 CASE에서 NULL 다루기
중요한 점: 비교값이 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는 그 명확함을 만들어주는 도구지.
GO TO FULL VERSION