본문 바로가기
SQL/내용 정리

조건에 따라 다른 연산하기(IF, CASE)

by mekite 2026. 4. 19.
IF

 

조건이 TURE면 값1, FALSE면 값2를 반환하는 함수

  • 2가지 결과만 처리(간단 분기/짧고 빠름)
  • 중첩 가능하지만 가독성이 떨어짐
-- 기본 문법

IF(조건, 참일 때 값, 거짓일 때 값)     -- 삼항연산자
-- 실습 1. 음식 타입을 'Korean'일 때는 '한식', 'Korean'이 아닌 경우에는 '기타'로 지정

SELECT
    restaurant_name,                         
    cuisine_type AS "원래 음식 타입",          -- 기존 음식 타입 그대로 출력
    IF(cuisine_type = 'Korean', '한식', '기타') AS "음식 타입"  -- 조건에 따라 한식/기타 분류
FROM 
    food_orders;                            
    

-- 실습 2. '문곡리'가 평택에만 해당될 때, 평택 '문곡리'만 '문가리'로 수정

SELECT
    addr AS "원래 주소",                          -- 기존 주소 그대로 출력
    REPLACE(addr, '문곡리', '문가리') AS "바뀐 주소"  -- '문곡리'를 '문가리'로 치환
FROM
    food_orders                               
WHERE
    addr LIKE '%평택%'                           -- 주소에 '평택' 포함
    AND addr LIKE '%문곡리%';                    -- 주소에 '문곡리' 포함 (→ 둘 다 만족하는 경우만 조회)


-- 실습 3. 잘못된 이메일 주소(gmail)만 수정을 해서 사용

SELECT
    substring(                                      -- 문자열 일부 추출
        if(email like '%gmail%',                    -- 이메일에 gmail 포함 시
            replace(email, 'gmail', '@gmail'),      -- gmail → @gmail 로 치환
            email),                                 -- 아니면 그대로 사용
        10) "이메일 도메인",                        -- 10번째 문자부터 잘라 도메인처럼 사용
    count(customer_id) "고객 수",                   -- 고객 수 집계
    avg(age) "평균 연령"                            -- 평균 나이
FROM
    customers                                 
GROUP BY 1;                                         -- 1번 컬럼(도메인) 기준 그룹화

 

 

 

CASE

 

여러 조건을 순차적으로 평가하여 처음 만족하는 결과 반환

  • 여러 조건 처리에 적합(복잡한 조건이어도 OK)
  • 이식성, 유지보수성 용이
-- 기본 문법

CASE
    WHEN 조건1 THEN 결과1
    WHEN 조건2 THEN 결과2
    ELSE 결과N
END
-- 실습 1. 음식 타입을 ‘Korean’ 일 때는 ‘한식’, ‘Japanese’ 혹은 ‘Chienese’ 일 때는
--        ‘아시아’, 그 외에는 ‘기타’ 라고 지정

SELECT
    CASE
        WHEN cuisine_type = 'Korean' THEN '한식'    -- Korean이면 '한식'
        -- Japanese/Chinese이면 '아시아'
        WHEN cuisine_type IN ('Japanese', 'Chinese') THEN '아시아'
        ELSE '기타'         -- 나머지는 '기타'
    END "음식타입",         -- 분류된 결과 컬럼명
    cuisine_type            -- 원래 음식 타입
FROM
    food_orders;            -- 주문 테이블


-- 실습 2. 음식 단가를 주문 수량이 1일 때는 음식 가격, 주문 수량이 2개 이상일 때는
--        음식가격/주문수량 으로 지정

SELECT
    order_id, 
    price,     
    quantity, 
    CASE
        WHEN quantity = 1 THEN price               -- 수량 1 → 가격 그대로
        WHEN quantity >= 2 THEN price/quantity     -- 수량 2 이상 → 가격 ÷ 수량
    END "음식 단가"                                -- 계산된 단가
FROM
    food_orders;                                   -- 주문 테이블
    
    
-- 실습 3. 10세 이상, 30세 미만의 고객의 나이와 성별로 그룹 나누기 (이름도 같이 출력)

-- 10세 이상 30세 미만 고객을 나이대 + 성별로 분류

SELECT
    CASE
        WHEN (age BETWEEN 10 AND 19) AND gender = 'male' THEN '10대 남성'     -- 10~19세 남성
        WHEN (age BETWEEN 10 AND 19) AND gender = 'female' THEN '10대 여성'   -- 10~19세 여성
        WHEN (age BETWEEN 20 AND 29) AND gender = 'male' THEN '20대 남성'     -- 20~29세 남성
        WHEN (age BETWEEN 20 AND 29) AND gender = 'female' THEN '20대 여성'   -- 20~29세 여성
    END "고객 분류",                -- 분류 결과 컬럼
    `name`,                         
    age,                           
    gender                        
FROM
    customers                    
WHERE
    age BETWEEN 10 AND 29;          -- 10세 이상 29세 이하 필터
    

-- 실습 4. 음식 단가, 음식 종류 별로 음식점 그룹 나누기

SELECT
    restaurant_name,                                                     
    price/quantity "단가",     -- 주문 금액 ÷ 수량 → 단가 계산
    cuisine_type,                                                          
    order_id,                                                          
    CASE
        WHEN (price/quantity <5000) AND cuisine_type='Korean' THEN '한식1'   -- 한식 + 저가
        WHEN (price/quantity BETWEEN 5000 AND 15000) AND cuisine_type='Korean' THEN '한식2' -- 한식 + 중가
        WHEN (price/quantity > 15000) AND cuisine_type='Korean' THEN '한식3' -- 한식 + 고가

        WHEN (price/quantity <5000) AND cuisine_type IN 
        	 ('Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian')
             THEN '아시아식1'     -- 아시아 + 저가
        WHEN (price/quantity BETWEEN 5000 AND 15000) AND cuisine_type IN
        	 ('Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian')
             THEN '아시아식2'     -- 아시아 + 중가
        WHEN (price/quantity > 15000) AND cuisine_type IN
        	 ('Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian')
             THEN '아시아식3'     -- 아시아 + 고가

        WHEN (price/quantity <5000) AND cuisine_type NOT IN
        	 ('Korean', 'Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian')
             THEN '기타1'     -- 기타 + 저가
        WHEN (price/quantity BETWEEN 5000 AND 15000) AND cuisine_type NOT IN
        	 ('Korean', 'Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian')
             THEN '기타2'     -- 기타 + 중가
        WHEN (price/quantity > 15000) AND cuisine_type NOT IN
        	 ('Korean', 'Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian')
             THEN '기타3'     -- 기타 + 고가
    END "식당 그룹"           -- 최종 그룹 결과
FROM
    food_orders;              -- 주문 테이블
    
    
-- 실습 5. 지역과 배달시간을 기반으로 배달수수료 구하기 (식당 이름, 주문 번호 함께 출력)
-- 지역 : 서울, 기타 - 서울일 때는 수수료 계산 * 1.1, 기타일 때는 곱하는 값 없음
-- 시간 : 25분, 30분 - 25분 초과하면 음식 가격의 5%, 30분 초과하면 음식 가격의 10%

SELECT
    CASE
        WHEN delivery_time > 30 THEN price * 0.1              -- 30분 초과 → 가격의 10%
             * IF(addr LIKE '%서울%', 1.1, 1)                 -- 서울이면 1.1배, 아니면 그대로
        WHEN delivery_time BETWEEN 26 AND 30 THEN price * 0.05 -- 25분 초과~30분 이하 → 가격의 5%
             * IF(addr LIKE '%서울%', 1.1, 1)                 -- 서울이면 1.1배
        ELSE 0                                                -- 25분 이하 → 수수료 없음
    END "수수료",
    restaurant_name,
    order_id,
    price,
    delivery_time,
    addr
FROM
    food_orders;
    
    
-- 실습 6. 주문 시기와 음식 수를 기반으로 배달할증료 구하기
-- 주문 시기 : 평일 기본료 = 3000 / 주말 기본료 = 3500
-- 음식 수 : 3개 이하이면 할증 없음 / 3개 초과이면 기본료 * 1.2

SELECT
    CASE
        WHEN day_of_the_week = 'weekday' THEN 3000            -- 평일 기본료 3000
             * IF(quantity > 3, 1.2, 1)                       -- 수량 3개 초과 시 1.2배
        WHEN day_of_the_week = 'weekend' THEN 3500            -- 주말 기본료 3500
             * IF(quantity > 3, 1.2, 1)                       -- 수량 3개 초과 시 1.2배
    END "배달할증료",
    restaurant_name,
    order_id,
    day_of_the_week,
    quantity
FROM
    food_orders;
-- 3강 완강 실습. 다음의 조건으로 배달시간이 늦었는지 판단하는 값을 만들어주세요. 
-- 1. SQL 문의 기본 구조로 시작
-- 2. 조건을 여러번 적용할 때 if, case 문 중 어떤 것을 이용할지 결정
-- 3. 조건에 ‘주중, 주말’ 조건과 ‘배달시간’ 조건을 동시에 줄 때 사용 할 논리연산자 결정
-- 주중 : 25분 이상, 주말 : 30분 이상

SELECT
    order_id,
    restaurant_name,
    day_of_the_week,
    delivery_time,
    CASE
        WHEN day_of_the_week = 'weekday' AND
             delivery_time >= 25 THEN 'late'     -- 주중 + 25분 이상 → 지연
        WHEN day_of_the_week = 'weekend' AND
             delivery_time >= 30 THEN 'late'     -- 주말 + 30분 이상 → 지연
        ELSE 'on-time'                           -- 그 외 → 정상
    END "지연여부"
FROM
    food_orders;