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 등
  • 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;

 

* 더 좋은 풀이가 있다면 알려주시면 감사하겠습니다. 🙏