코딩테스트

[26.03.16 코테/회고(MySQL/Oracle)]-자동차 대여 기록 별 대여 금액 구하기

지니248 2026. 3. 16. 14:01

Lv4. 자동차 대여 기록 별 대여 금액 구하기 (MySQL)

링크: https://school.programmers.co.kr/learn/courses/30/lessons/151141?language=mysql

 

내가 작성한 코드

WITH RENTAL_INFO AS (
    SELECT H.HISTORY_ID, C.CAR_TYPE, C.DAILY_FEE, DATEDIFF(H.END_DATE, H.START_DATE) + 1 AS DURATION, -- 대여 기간
    CASE WHEN DATEDIFF(H.END_DATE, H.START_DATE) + 1 >= 90 THEN '90일 이상'
         WHEN DATEDIFF(H.END_DATE, H.START_DATE) + 1 >= 30 THEN '30일 이상'
         WHEN DATEDIFF(H.END_DATE, H.START_DATE) + 1 >= 7 THEN '7일 이상'
         ELSE NULL 
         END AS DURATION_TYPE -- 할인율이 적용되는 대여 기간 종류
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H
    JOIN CAR_RENTAL_COMPANY_CAR C
      ON H.CAR_ID = C.CAR_ID
    WHERE C.CAR_TYPE = '트럭')

SELECT R.HISTORY_ID, FLOOR(R.DAILY_FEE * R.DURATION * (1 - IFNULL(P.DISCOUNT_RATE, 0) / 100)) AS FEE
FROM RENTAL_INFO R
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN P
       ON R.DURATION_TYPE = P.DURATION_TYPE
      AND R.CAR_TYPE = P.CAR_TYPE
ORDER BY FEE DESC, HISTORY_ID DESC;

 

Oracle

WITH RENTAL_INFO AS (
    SELECT H.HISTORY_ID, C.CAR_TYPE, C.DAILY_FEE, (H.END_DATE - H.START_DATE) + 1 AS DURATION, -- 대여 기간
    CASE WHEN (H.END_DATE - H.START_DATE) + 1 >= 90 THEN '90일 이상'
         WHEN (H.END_DATE - H.START_DATE) + 1 >= 30 THEN '30일 이상'
         WHEN (H.END_DATE - H.START_DATE) + 1 >= 7 THEN '7일 이상'
         END AS DURATION_TYPE -- 할인율이 적용되는 대여 기간 종류
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H
    JOIN CAR_RENTAL_COMPANY_CAR C
      ON H.CAR_ID = C.CAR_ID
    WHERE C.CAR_TYPE = '트럭')

SELECT R.HISTORY_ID, TRUNC(R.DAILY_FEE * R.DURATION * (1 - NVL(P.DISCOUNT_RATE, 0) / 100)) AS FEE
FROM RENTAL_INFO R
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN P
       ON R.DURATION_TYPE = P.DURATION_TYPE
      AND R.CAR_TYPE = P.CAR_TYPE
ORDER BY FEE DESC, HISTORY_ID DESC;

-- 날짜 연산이 가능하다
-- IFNULL이 아닌 NVL로 사용한다
-- TRUNC 함수 사용이 가능하다

문제 회고

1. LEFT JOIN을 하지 않고 그냥 JOIN을 사용함

- JOIN을 사용한 결과 에러 발생

- 원인을 찾기 위해 제미나이 활용

- 틀린 이유:

   - 할인율이 적용되는 대여 기간 종류에서 대여기간이 7일 미만인 경우 할인 정책이 없음

   - 하지만 대여기간이 7일 미만인 단기 대여 기록도 포함되어 있음

   - 임의로 '7일 미만-할인정책X' 라는 CASE 구문에 추가해 확인하였음 (↓ 아래 사진1 참조)

- 해결 방법:

   - 단기 대여 기록도 최종 리스트에 반드시 포함되어야 하므로 왼쪽 테이블(대여 기록)을 기준으로 데이터 보존

2. IFNULL을 사용하지 않음

- FEE 값에 마이너스가 나옴 (↓ 아래 사진2 참조)

- 틀린 이유:

   - LEFT JOIN을 하면 할인 정책이 없는 단기 대여 건의 할인율이 NULL로 채워짐 

- 해결 방법:

   - IFNULL(P.DISCOUNT_RATE, 0)을 사용하여 NULL을 숫자 0으로 강제 변환

   - 이를 통해 할인율 0%가 정상적으로 적용되어 원금이 계산되었음

 

사진1) 단기 대여 기록 확인
사진2) 마이너스인 결과가 나온 FEE 값