Case
1. CASE 문 소개
- 우리는 지금까지 데이터를 있는 그대로 조회하거나(
SELECT), 여러 테이블을 합치거나(JOIN,UNION), 특정 조건으로 걸러내는(WHERE) 방법을 배웠습니다. - 즉, 데이터의 '구조'를 바꾸거나 '범위'를 한정하는 기술들이었습니다.
- 이제부터 배울
CASE문은 한 차원 다른 역할을 합니다.
1.1 CASE 문의 역할
CASE문은 데이터 '자체'를 동적으로 가공하고 새로운 의미를 부여하는, 데이터에 멋진 옷을 입히는 기술입니다.- 마치
IF-THEN-ELSE처럼, 특정 조건에 따라 다른 값을 출력하게 만드는 SQL의 강력한 조건부 로직 도구입니다.
1.2 문제 상황
"상품 목록을 조회하는데, 그냥 가격만 보여주지 말고, 가격대에 따라 '고가', '중가', '저가'와 같은 알아보기 쉬운 등급을 옆에 함께 표시하고 싶다."
- 10만원 이상: '고가'
- 3만원 이상 10만원 미만: '중가'
- 3만원 미만: '저가'
애플리케이션 vs SQL
물론 이 작업은 데이터베이스에서 원본 데이터를 모두 가져온 뒤, 자바나 파이썬 같은 애플리케이션 코드에서 if-else 문으로 처리할 수도 있습니다. 하지만 CASE 문을 사용하면 간단한 보고서나 데이터 분석을 할 때, 쿼리 하나만으로 원하는 최종 결과물을 바로 얻을 수 있어 매우 편리합니다.
2. CASE 문의 두 가지 종류
CASE문은 크게 두 가지 방식으로 나눌 수 있습니다.- **단순 CASE 문(Simple CASE Expression)**과 **검색 CASE 문(Searched CASE Expression)**입니다.
- 이름은 어렵지만, 실제 사용법은 매우 직관적입니다.
2.1 단순 CASE 문 (Simple CASE Expression)
- 단순
CASE문은 특정 하나의 컬럼이나 표현식의 값에 따라 결과를 다르게 하고 싶을 때 사용합니다. - 특정 값을 기준으로 "이 값이 A면 X, B면 Y, 그 외에는 Z"와 같이 명확하게 분기할 때 유용합니다.
단순 CASE 문의 기본 문법
CASE 비교대상_컬럼_또는_표현식
WHEN 값1 THEN 결과1
WHEN 값2 THEN 결과2
...
ELSE 그_외의_경우_결과
END
비교대상_컬럼_또는_표현식:WHEN절에서 비교할 대상이 되는 컬럼 또는 표현식입니다.WHEN 값 THEN 결과:비교대상_컬럼_또는_표현식의 값이값과 같을 경우결과를 반환합니다.ELSE 결과: 위에 명시된WHEN조건들 중 어느 것 하나도 참이 아닐 경우,ELSE뒤의 결과를 반환합니다.ELSE를 생략했는데 모든WHEN조건이 거짓이면NULL이 반환됩니다.
실행 순서
단순 CASE 문도 위에서 아래 순서대로 조건을 평가하며, 가장 먼저 일치하는 WHEN 절을 만나는 순간 그 THEN의 결과를 반환하고 즉시 평가를 종료합니다.
단순 CASE 문 예제: 주문 상태(status)를 한글로 표시하기
- 우리 쇼핑몰의
orders테이블에는 주문 상태를PENDING,COMPLETED,SHIPPED,CANCELLED와 같은 영어로 저장하고 있습니다. - 고객에게는 이 상태를 한글로 보여주고 싶습니다.
SELECT
order_id,
user_id,
product_id,
quantity,
status,
CASE status
WHEN 'PENDING' THEN '주문 대기'
WHEN 'COMPLETED' THEN '결제 완료'
WHEN 'SHIPPED' THEN '배송'
WHEN 'CANCELLED' THEN '주문 취소'
ELSE '알 수 없음' -- 예상치 못한 상태 값 처리
END AS status_korean
FROM
orders;
실행 결과
| order_id | user_id | product_id | quantity | status | status_korean |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 1 | COMPLETED | 결제 완료 |
| 2 | 1 | 4 | 2 | COMPLETED | 결제 완료 |
| 3 | 2 | 2 | 1 | SHIPPED | 배송 |
| 4 | 3 | 4 | 1 | COMPLETED | 결제 완료 |
| 5 | 4 | 3 | 1 | PENDING | 주문 대기 |
| 6 | 5 | 1 | 1 | COMPLETED | 결제 완료 |
| 7 | 2 | 1 | 2 | SHIPPED | 배송 |
- 단순
CASE문은 이렇게 하나의 기준 값에 따라 명확하게 분류할 때 깔끔하고 가독성이 좋습니다.
2.2 검색 CASE 문 (Searched CASE Expression)
- 검색
CASE문은 단순CASE문처럼 하나의 특정 값을 비교하는 대신, 각WHEN절에 독립적인 조건식을 사용하여 복잡한 논리를 구현할 때 사용합니다. - 앞서 만난 문제 상황처럼 '가격이 얼마 이상', '날짜가 언제 이전'과 같은 범위 조건이나 여러 컬럼을 조합한 복합적인 조건이 필요할 때 주로 사용됩니다.
검색 CASE 문의 기본 문법
CASE
WHEN 조건1 THEN 결과1
WHEN 조건2 THEN 결과2
...
ELSE 그_외의_경우_결과
END
WHEN 조건 THEN 결과:WHEN뒤의 조건이 참(true)일 경우,THEN뒤의 결과를 반환합니다. 여기서조건은price >= 100000,category = '도서'등 다양한 비교 연산자와 논리 연산자(AND,OR,NOT)를 포함할 수 있습니다.ELSE 결과: 위에 명시된WHEN조건들 중 어느 것 하나도 참이 아닐 경우,ELSE뒤의 결과를 반환합니다.ELSE를 생략했는데 모든WHEN조건이 거짓이면NULL이 반환됩니다.
실행 순서
검색 CASE 문도 위에서 아래 순서대로 조건을 평가하며, 가장 먼저 참이 되는 WHEN 절을 만나는 순간 그 THEN의 결과를 반환하고 즉시 평가를 종료합니다. 이 순서가 매우 중요합니다.
검색 CASE 문 예제: 상품 가격에 따라 등급 표시하기
- 이제 강의 시작 시점에 제시했던 문제, 즉 상품 가격에 따라 '고가', '중가', '저가' 등급을 표시하는 문제를 검색
CASE문으로 해결해 보겠습니다.
SELECT
name,
price,
CASE
WHEN price >= 100000 THEN '고가'
WHEN price >= 30000 THEN '중가'
ELSE '저가'
END AS price_label
FROM
products;
- 여기서
AS price_label을 사용해,CASE문 전체가 만들어내는 결과에price_label이라는 새로운 컬럼명을 붙여주었습니다. - 이 쿼리는
products테이블의 각 행마다 다음의 로직을 수행합니다.- 가격이 10만원 이상인가? 맞으면 '고가'를 반환하고
CASE문을 끝냅니다. - (1번이 아니라면) 가격이 3만원 이상인가? 맞으면 '중가'를 반환하고 끝냅니다.
- (1, 2번이 모두 아니라면)
ELSE에 따라 '저가'를 반환합니다.
- 가격이 10만원 이상인가? 맞으면 '고가'를 반환하고
실행 결과
| name | price | price_label |
|---|---|---|
| 프리미엄 게이밍 마우스 | 75000 | 중가 |
| 기계식 키보드 | 120000 | 고가 |
| 4K UHD 모니터 | 350000 | 고가 |
| 관계형 데이터베이스 입문 | 28000 | 저가 |
| 고급 가죽 지갑 | 150000 | 고가 |
| 스마트 워치 | 280000 | 고가 |
- 보는 것과 같이, 원본 데이터는 전혀 건드리지 않고, 조회 결과에만 우리가 정의한 비즈니스 로직에 따라 새로운 값을 동적으로 생성하여 보여주었습니다.
3. WHEN 절의 순서
3.1 순서가 중요한 이유
- 앞서
CASE문은 위에서 아래로 순차적으로 평가하며, 가장 먼저 참이 되는 조건을 만나는 순간 실행을 멈춘다고 강조했습니다. - 이 점이 검색
CASE문에서는 특히 중요합니다. - 만약 조건을 잘못 배치하면 예상과 다른 결과가 나올 수 있습니다.
3.2 잘못된 순서의 예
- 만약 위 쿼리에서
WHEN price >= 30000조건을WHEN price >= 100000조건보다 먼저 배치했다면 어떻게 될까요?
-- 잘못된 순서의 예 (의도와 다른 결과)
SELECT
name,
price,
CASE
WHEN price >= 30000 THEN '중가' -- 이 조건이 먼저 평가된다
WHEN price >= 100000 THEN '고가'
ELSE '저가'
END AS price_label
FROM
products;
실행 결과
| name | price | price_label |
|---|---|---|
| 프리미엄 게이밍 마우스 | 75000 | 중가 |
| 기계식 키보드 | 120000 | 중가 |
| 4K UHD 모 니터 | 350000 | 중가 |
| 관계형 데이터베이스 입문 | 28000 | 저가 |
| 고급 가죽 지갑 | 150000 | 중가 |
| 스마트 워치 | 280000 | 중가 |
프리미엄 게이밍 마우스(75000원): 75000원은 30000원 이상이므로 '중가'로 분류됩니다. (올바름)기계식 키보드(120000원): 120000원은 30000원 이상이므로 '중가'로 분류됩니다. (틀림! '고가'여야 함)
3.3 올바른 조건 배치 전략
조건 순서 가이드
검색 CASE 문을 사용할 때는 조건의 순서를 신중하게 고려해야 합니다. 더 포괄적인(범위가 넓은) 조건보다는 더 구체적인(범위가 좁은) 조건을 먼저 배치하는 것이 일반적입니다.
4. CASE 문의 다양한 활용
4.1 ORDER BY 절에서 사용하기
CASE문은SELECT절 외에도ORDER BY,GROUP BY,WHERE절 등 다양한 SQL 구문과 함께 사용될 수 있습니다.- 예를 들어, 상품을 '고가', '중가', '저가' 순서로 정렬하고 싶다면
ORDER BY절에CASE문을 사용할 수 있습니다.
SELECT
name,
price,
CASE
WHEN price >= 100000 THEN '고가'
WHEN price >= 30000 THEN '중가'
ELSE '저가'
END AS price_label
FROM
products
ORDER BY
CASE
WHEN price >= 100000 THEN 1 -- 고가: 1
WHEN price >= 30000 THEN 2 -- 중가: 2
ELSE 3 -- 저가: 3
END ASC, -- 숫자가 작은 순서대로 정렬
price DESC; -- 같은 등급 내에서는 가격 내림차순
실행 결과
| name | price | price_label |
|---|---|---|
| 4K UHD 모니터 | 350000 | 고가 |
| 스마트 워치 | 280000 | 고가 |
| 고급 가죽 지갑 | 150000 | 고가 |
| 기계식 키보드 | 120000 | 고가 |
| 프리미엄 게이밍 마우스 | 75000 | 중가 |
| 관계형 데이터베이스 입문 | 28000 | 저가 |
- 보는 것처럼,
price_label컬럼의 '고가', '중가', '저가' 문자열 순서가 아닌, 우리가CASE문에서 지정한 1, 2, 3의 숫자 순서대로 정렬된 것을 확인할 수 있습니다. - 이렇게
CASE문은 데이터의 표현뿐만 아니라 정렬, 그룹화 등 다양한 로직에 활용할 수 있습니다.
5. CASE 문과 GROUP BY
5.1 데이터 분류 및 그룹핑
- 이것이
CASE문의 기본입니다. 하지만CASE문의 진정한 힘은 다른 SQL 구문, 특히 집계 함수나GROUP BY와 결합될 때 발휘됩니다. - 단순히 등급을 표시하는 것을 넘어, '고가', '중가', '저가' 상품이 각각 몇 개씩 있는지 집계하려면 어떻게 해야 할까요?