Coding/SQL
[프로그래머스-SQL] 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기
kangplay
2025. 3. 6. 17:29
문제
https://school.programmers.co.kr/learn/courses/30/lessons/157339
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
프로그래머스 LV4
설명
크게 어렵지는 않지만 조건이 많아 복잡했던 문제였다.
- 2022년 11월 1일부터 2022년 11월 30일까지 대여가 가능하기 위해서는, NOT (ch.start_date > '2022-11-30' OR ch.end_date < '2022-11-01') 조건이 필요하다. (처음에는 end_date가 11월 내에 있으면 제외했는데, start가 11월이고, end가 12월이면 포함해야하는데도 불구하고 제외된다.)
- discount 속성에서 %를 제외한 부분을 숫자로 변환했어야하는데, 다음과 같은 함수를 적용했다.
- replace : 특정 문자를 다른 문자로 치환해줄 때 사용
- replace(컬럼명, 바꾸고 싶은 문자, 바뀔 문자)
- cast : 데이터 타입을 형변환해줄 때 사용
- cast (변환할 값 as 데이터타입) *데이터 타입: unsigned, decimal, char, date 등
- replace : 특정 문자를 다른 문자로 치환해줄 때 사용
- union all을 사용할 때 order by는 select 문에 모두 적용하는 게 아니라, 맨 마지막에 적용해야 한다.
구현
-- 세단 또는 SUV 이면서 요구된 기간 내에 대여가 된 차
with except_car as
(
select cr.car_id as car_id
from car_rental_company_car cr
join car_rental_company_rental_history ch on cr.car_id = ch.car_id
where cr.car_type IN ('세단', 'SUV')
AND NOT (ch.start_date > '2022-11-30' OR ch.end_date < '2022-11-01')
) ,
-- 30일 이상에 대한 할인 조건이 있으며, except_car에 포함되지 않는 차
include_car_with_discount as
(
select cr.car_id ,
CAST(REPLACE(cp.discount_rate, '%', '') AS UNSIGNED) AS discount_numeric,
cr.daily_fee as daily_fee,
cr.car_type as car_type
from car_rental_company_car cr
join car_rental_company_discount_plan cp on cr.car_type = cp.car_type
where cr.car_type IN ('세단', 'SUV')
and cp.duration_type = '30일 이상'
and cr.car_id NOT IN (select car_id from except_car)
),
-- 30일 이상에 대한 할인 조건이 없으며, except_car에 포함되지 않는 차
include_car_without_discount as
(
select cr.car_id ,
cr.daily_fee as daily_fee,
cr.car_type as car_type
from car_rental_company_car cr
left join car_rental_company_discount_plan cp on (cr.car_type = cp.car_type and cp.duration_type = '30일 이상')
where cr.car_type IN ('세단', 'SUV')
and cr.car_id NOT IN (select car_id from except_car)
and cp.duration_type is null
)
(select car_id, car_type, round(daily_fee*30*(100-discount_numeric)*0.01,0) as fee
from include_car_with_discount
where daily_fee*30*(100-discount_numeric)*0.01 between 500000 and 2000000)
union all
(select car_id, car_type, round(daily_fee*30,0) as fee
from include_car_without_discount
where daily_fee*30 between 500000 and 2000000)
ORDER BY fee DESC, car_type ASC, car_id DESC;
* 더 좋은 풀이가 있다면 알려주시면 감사하겠습니다. 🙏