코딩테스트 준비/SQL문법

[프로그래머스 LV4] - 자동차 대여 기록 별 대여 금액 구하기(string, date) SQL(how to use 'with clause' )

SeoburiFaust 2024. 2. 18. 17:49

문제

https://school.programmers.co.kr/learn/courses/30/lessons/151141

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

접근방법

세 테이블을 한 번에 join 시킨 후 해결하려고 했지만,

실패했다.

 

특히, 대여기간 별로 할인율을 다르게 적용하는 부분이 어려웠다.

case문을 사용해야 할 거 같은데, 어디다가 위치시켜야 할 지 감이 오지 않았다.

 

그래서 다른 사람 답안을 참고했다.

 

with를 써서 해결한 것을 볼 수 있었다.

rental_date_per_history에서 각 기록별 rental_date를 가져온 후

rental_date_type_per_history에서는 rental_date를 이용해 rental_date_type을 구했다.(rental_date_type = duration_type)

위 두개를 한 번 에 작성할 수 있지만, 2개로 나눠서 작성하는 것이 이해가 편하다.

 

discount_rate_per_history에서는 rental_date_type 구한 것을 이용해,

discount_rate을 계산해 추가한다.

 

여기서 포인트는 left join과 coalesce인데,

 

left_join을 해줘야지만, 7일 이하 rental_date_type을 가진 칼럼이 살아남고,

discount_rate의 값이 null로 설정된다.

 

coalesce를 통해 discount_rate의 값이 null인 경우 0으로 설정해 계산하기 편리하게 만들어 줄 수 있다.

코드

-- 코드를 입력하세요
with rental_date_per_history as (   #각 history마다 rental_date 구하기
select *, datediff(end_date, start_date) + 1 as rental_date
from car_rental_company_rental_history 
natural join car_rental_company_car),
rental_date_type_per_history as (   #각 history마다 rental_date_type구하기
select *, 
    case when rental_date < 7 then null
    when rental_date < 30 then '7일 이상'
    when rental_date < 90 then '30일 이상'
    else '90일 이상' end as rental_date_type
from rental_date_per_history),
discount_rate_per_history as (  #위 두개의 table을 이용해 discount_rate구하기
select h.history_id, h.daily_fee, rental_date, h.car_type, coalesce(p.discount_rate, 0) as discount_rate
from rental_date_type_per_history as h
left join car_rental_company_discount_plan as p
on h.car_type = p.car_type and rental_date_type = duration_type)

select history_id, floor(daily_fee * rental_date * (1-discount_rate/100)) as fee
from discount_rate_per_history
where car_type = '트럭'
order by floor(daily_fee * rental_date * (1-discount_rate/100)) desc,
history_id desc

개선할 점

문제가 복잡할 땐, with 절을 사용해보자.

 

 

참고 :

https://developevolvify.tistory.com/408