1 분 소요

문제 링크

정답

-- 대여 중인 자동차 정보
-- CAR_RENTAL_COMPANY_CAR: CAR_ID, CAR_TYPE, DAILY_FEE, OPTIONS

-- 자동차 대여 기록 정보
-- CAR_RENTAL_COMPANY_RENTAL_HISTORY: HISTORY_ID, CAR_ID, START_DATE, END_DATE

-- 자동차 종류 별 대여 기간 종류 별 할인 정책
-- CAR_RENTAL_COMPANY_DISCOUNT_PLAN: PLAN_ID, CAR_TYPE, DURATION_TYPE, DISCOUNT_RATE

-- 11월 달에 대여 예약된 자동차 ID
WITH RENT_NOV AS (
    SELECT CAR_ID
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE START_DATE <= '2022-11-30'
      AND END_DATE >= '2022-11-01'
),
-- 11월에 대여 가능한 자동차 (SUV, 세단)
    AVAILABLE_NOV AS (
    SELECT T1.CAR_ID, T1.CAR_TYPE, T1.DAILY_FEE
    FROM CAR_RENTAL_COMPANY_CAR AS T1
    LEFT OUTER JOIN RENT_NOV AS T2 
        ON T1.CAR_ID = T2.CAR_ID
    WHERE T2.CAR_ID IS NULL
        AND (T1.CAR_TYPE = 'SUV' OR T1.CAR_TYPE = '세단')
),
-- 차종 별 30일 이상 대여비
    FEE_BY_CAR_TYPE AS (
    SELECT CAR_TYPE, (1 - 0.01 * DISCOUNT_RATE) AS FINAL_RATE
    FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN
    WHERE DURATION_TYPE = '30일 이상'
    AND (CAR_TYPE = 'SUV' OR CAR_TYPE = '세단')
)

SELECT T1.CAR_ID, 
    T1.CAR_TYPE, 
    ROUND(T1.DAILY_FEE * T2.FINAL_RATE * 30) AS FEE # 30 대여 금액
FROM AVAILABLE_NOV AS T1
JOIN FEE_BY_CAR_TYPE AS T2
    ON T1.CAR_TYPE = T2.CAR_TYPE
WHERE ROUND(T1.DAILY_FEE * T2.FINAL_RATE * 30) BETWEEN 500000 AND 2000000
ORDER BY 3 DESC, 2 ASC, 1 DESC;

✅ Point

  • 11월에 대여 가능한 차량 추리기: AVAILABLE_NOV
    • 동일한 CAR_ID에 대해 여러 예약 기록 존재 가능성 있음
    • 따라서 “11월과 겹치는 예약이 단 하나라도 있으면 제외” → LEFT JOIN + IS NULL로 처리:
    • 날짜 조건: START_DATE <= '2022-11-30' AND END_DATE >= '2022-11-01'
  • 할인 정책 고려: 30일 이상: FEE_BY_CAR_TYPE
    • CAR_TYPE마다 DURATION_TYPE별 할인율이 다르므로, “30일 이상”에 해당하는 데이터만 필터링해서 FEE_BY_CAR_TYPE 생성
    • 할인 비율을 (1 - 0.01 * DISCOUNT_RATE)로 미리 계산해 요금 계산을 간편하게 만듦
  • 최종 요금 계산과 필터링
    • 30일 대여 요금 = DAILY_FEE × 할인율 × 30일
    • SQL에서는 500000 <= x <= 2000000 표현 불가!
      • 반드시 BETWEEN … AND … 또는 x >= … AND x <= … 로 표현해야 함