⚠️ 읽기 전 주의사항
본인은 현업에서 3년 간 SQL을 쓰면서 SQL에 매우 익숙한 상황.
내일배움캠프에서 SQL 강의를 들으면서 이미 아는 내용이라 쿼리 길게 적기 싫다고,
수업 의도와 다른 꼼수 쿼리를 남발 중...
SQL이 처음이라면 강의 의도대로 하시길...
CASE WHEN)우리가 원하는 결과물

강의가 의도한 쿼리
select name '이름',
age '나이',
gender '성별',
case when (age between 10 and 19) and gender='male' then "10대 남자"
when (age between 10 and 19) and gender='female' then "10대 여자"
when (age between 20 and 29) and gender='male' then "20대 남자"
when (age between 20 and 29) and gender='female' then "20대 여자" end "고객 그룹"
from customers
where age between 10 and 29;
흠.. 🤔
근데 너무 길지 않나? 왜 반복되게 여러 번 적어야하지?
나의 꼼수 쿼리
select name '이름'
, age '나이'
, gender '성별'
, concat(substr(age,1,1), '0대 ', if(gender='female', '여자', '남자')) "고객 그룹"
from customers c
where age >= 10 and age < 30;
주요 사항
CASE 문으로 4줄이었던 쿼리를 CONCAT과 IF를 사용하여 1줄로 만듦SUBSTR로 나이에서 앞자리 숫자 한개만 가져옴WHERE절에서 BETWEEN 이 아닌 비교연산 적용우리가 원하는 결과물

강의가 의도한 쿼리
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
강의에서 한식1, 한식2, 한식3, 아시아식1, 아시아식2, 아시아식3, 기타1, 기타2, 기타3 의 총 9개의 경우의 수를 대상으로 모두 CASE WHEN을 각각 사용했다.
한식/아시아식/기타로 분류하는 각 코드를 매번 반복하고,
그럴 때마다 IN 으로 수많은 텍스트를 치는 것이 불필요하다고 생각했음
나의 꼼수 쿼리
select restaurant_name '식당명'
, price/quantity '단가'
, cuisine_type '음식 종류'
, order_id '주문 번호'
, concat(case when cuisine_type = 'Korean' then '한식'
when cuisine_type in ('Japanese', 'Chinese', 'Thai', 'Vietnamese', 'Indian') then '아시아식'
else '기타' end
, case when price/quantity < 5000 then 1
when price/quantity <= 15000 then 2
else 3 end
) '식당 그룹'
from food_orders
주요 사항
cuisine_type)별로 CASE를 나누고, '한식'과 '아시아식'이 아닌 것은 ELSE로 '기타'로 줌price/quantity)별로 조건을 줌BETWEEN을 혼합해서 사용해, 1그룹은 5000원 미만, 2그룹은 5000원 이상 15000원 이하, 3그룹은 15000원 초과로, 이상/이상/초과/미만이 모두 사용됨.우리가 원하는 결과물

강의가 의도한 쿼리
select restaurant_name,
order_id,
delivery_time,
price,
addr,
case when delivery_time>25 and delivery_time<=30 then price*1.05*(if(addr like '%서울%', 1.1, 1))
when delivery_time>30 then price*1.1*(if(addr like '%서울%', 1.1, 1))
else 0 end "수수료"
from food_orders
지역별 할증 쿼리를 두번 쓰는게 맘에 들지 않아, 반복을 줄이고자 함
나의 꼼수 쿼리
select order_id '주문번호'
, restaurant_name '식당'
, addr '주소'
, delivery_time '배달 시간'
, price '음식 가격'
, price * if(
substr(addr, 1, 2) = '서울', 1.1, 1
) * case when delivery_time > 30 then 0.1
when delivery_time > 25 then 0.05
else 0 end '배달수수료'
from food_orders
우리가 원하는 결과물

강의가 의도한 쿼리
select order_id '주문번호'
, restaurant_name '식당'
, day_of_the_week '주문시기'
, quantity '음식 수'
, case when day_of_the_week='Weekday' then 3000*if(quantity>3,1.2,1)
when day_of_the_week='Weekend' then 3500*if(quantity>3,1.2,1)
end '배달할증료'
from food_orders
day_of_the_week은 평일과 주말 두가지 경우만 있는데, 굳이 CASE를 써야할 필요가 없음
그리고 불필요하게 *if(quantity>3,1.2,1)도 두번 적은게 거슬렸음
나의 꼼수 쿼리
select order_id '주문번호'
, restaurant_name '식당'
, day_of_the_week '주문시기'
, quantity '음식 수'
, if(day_of_the_week='Weekday', 3000, 3500) * if(quantity>3,1.2,1) '배달할증료'
from food_orders
IF문 2개를 곱해줘서 간단하게 한 줄로 마무리!!
# 숫자로 변경
cast(if(컬럼명='바꿀 값', 바꿀숫자, 컬럼명) as decimal)
# 문자로 변경
concat(컬럼명1, '-', cast(컬럼명2 as char))
회사에서 MySQL 을 사용해서, CAST 함수를 쓸 일은 없었지만...
언젠가 다른 SQL을 쓸 수도 있으니 알아두자.