[programmers/SQL] 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기

songeunm·2025년 3월 28일

PS - sql

목록 보기
54/58
post-thumbnail

문제

문제 흐름

예전에 풀었던 문제임에도 여전히 어렵다. 또 헤맸다.
그전에도 프로그래머스에서 가장 풀기 어려운 SQL 문제라고 생각했었다.
여전히 같은 부분을 캐치하지 못하고 이전 풀이를 참고하여 여러 번의 시도 끝에 풀이했다.
이래서 복습이 중요한가보다.


이 문제는 크게 3가지 흐름이 있고, 주의해야할 점이 1가지 있다.

  1. "세단", "SUV" 차량을 필터링한다.
  2. car_rental_company_discount_plandiscount_rate를 참고하여 30일동안 대여시 할인 적용가인 fee를 계산하고, fee가 500000이상, 2000000미만이도록 필터링한다.
  3. '2022-11-01'부터 '2022-11-30'까지 대여 가능한 차량을 필터링한다.

여기서 주의해야할 부분은 3번이다.
11월에 대여를 제외한 기록의 차량이 11월에 빌릴 수 있는 차량은 아니다.
이게 무슨 소리냐면?
만약 A차량이
2022-09-10 ~ 2022-09-20,
2022-11-10 ~ 2022-11-20
와 같은 대여 기록이 있다고 치자.
사람이 이렇게 눈으로 본다면 당연히 대여하지 못하는 차량으로 분류할 것이다.
여기서 "2022-11-01 ~ 2022-11-30 사이에 대여 기간이 겹치지 않는 기록에 있는 차량중에~"라고 하게되면 A차량의 경우 두번째인 2022-11-10 ~ 2022-11-20기록이 걸러질 것이고, 2022-09-10 ~ 2022-09-20 기록만 남게된다.
이렇게 남은 차량을 대여 가능한 차량으로 본다면 잘못된 필터링을 하게 되는 것이다.

...
예시를 들었더니 더 복잡하게 느껴지는 것 같기도 하다.
아무튼 이때문에 해당 기간과 대여 기간이 겹치는 모든 car_id를 추출한 뒤,
car_id들에 포함되지 않는 차량을 필터링해야한다.

나머지는 평소와 같이 JOIN하고 필터링해주면 된다.

코드

WITH rented AS (
    SELECT DISTINCT car_id
    FROM car_rental_company_rental_history
    WHERE start_date <= "2022-11-30" AND end_date >= "2022-11-01"
)

SELECT car_id, c.car_type, round(daily_fee*30*(100-discount_rate)/100) fee
FROM car_rental_company_car c
LEFT JOIN car_rental_company_discount_plan d
ON c.car_type = d.car_type
AND c.car_type in ("세단", "SUV")
AND d.duration_type = "30일 이상"
WHERE car_id NOT IN (SELECT * FROM rented)
    AND daily_fee*30*(100-discount_rate)/100 BETWEEN 500000 AND 2000000-1
ORDER BY 3 DESC, 2 ASC, 1 DESC;
profile
데굴데굴 구르는 개발자 지망생

0개의 댓글