데이터베이스/ORACLE
[ORACLE] 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기
썬키
2024. 6. 3. 13:10
링크를 클릭하면 해당 문제로 이동합니다.
접근하기
2022년 11월 1일부터 2022년 11월 30일까지 대여가 가능한 차량을 먼저 조회하고
기타 부수적인 조건(30일간의 대여 금액이 50만원 이상 200만원 미만)을 더해서 문제를 풀면 되겠다.
코드
-- 2022년 11월 1일부터 2022년 11월 30일까지 대여 가능한 '세단' 이나 'SUV'
-- END_DATE가 2022년 11월 1일 이후 & START_DATE가 2022년 12월 01일 이전이면 대여 불가능
SELECT A.CAR_ID
FROM CAR_RENTAL_COMPANY_CAR A
, CAR_RENTAL_COMPANY_RENTAL_HISTORY B
WHERE A.CAR_ID = B.CAR_ID
AND A.CAR_TYPE IN ('세단', 'SUV')
AND TO_CHAR(B.END_DATE, 'YYYYMMDD') >= '20221101'
AND TO_CHAR(B.START_DATE, 'YYYYMMDD') < '20221201';
문제를 풀면서 제일 많이 고민 되었던 부분이
어떻게하면 문제에 기재된 기간 내에 대여 가능한 차량 데이터를 추출할 수 있을까였는데
위와 같이 작성하고 상기 쿼리에서 추출된 데이터를 제외하면 되겠다.
SELECT CAR_ID
, CAR_TYPE
, CASE WHEN CAR_TYPE = '세단' THEN (DAILY_FEE - (DAILY_FEE * 0.08)) * 30
ELSE (DAILY_FEE - (DAILY_FEE * 0.05)) * 30
END AS FEE
FROM CAR_RENTAL_COMPANY_CAR
WHERE CAR_TYPE IN ('세단', 'SUV')
AND CAR_ID NOT IN (
SELECT A.CAR_ID
FROM CAR_RENTAL_COMPANY_CAR A
, CAR_RENTAL_COMPANY_RENTAL_HISTORY B
WHERE A.CAR_ID = B.CAR_ID
AND A.CAR_TYPE IN ('세단', 'SUV')
AND TO_CHAR(B.END_DATE, 'YYYYMMDD') >= '20221101'
AND TO_CHAR(B.START_DATE, 'YYYYMMDD') < '20221201'
)
상기에서 작성한 쿼리를 WHERE 절의 NOT IN으로 넣어주면 대여 가능 차량이 추출되고
CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 확인한 데이터로
해당 차량들의 DAILY_FEE 컬럼 값에 할인율을 적용시키면 FEE 값이 산출된다.
SELECT A.*
FROM (
SELECT CAR_ID
, CAR_TYPE
, CASE WHEN CAR_TYPE = '세단' THEN (DAILY_FEE - (DAILY_FEE * 0.08)) * 30
ELSE (DAILY_FEE - (DAILY_FEE * 0.05)) * 30
END AS FEE
FROM CAR_RENTAL_COMPANY_CAR
WHERE CAR_TYPE IN ('세단', 'SUV')
AND CAR_ID NOT IN (
SELECT A.CAR_ID
FROM CAR_RENTAL_COMPANY_CAR A
, CAR_RENTAL_COMPANY_RENTAL_HISTORY B
WHERE A.CAR_ID = B.CAR_ID
AND A.CAR_TYPE IN ('세단', 'SUV')
AND TO_CHAR(B.END_DATE, 'YYYYMMDD') >= '20221101'
AND TO_CHAR(B.START_DATE, 'YYYYMMDD') < '20221201'
)
) A
WHERE A.FEE BETWEEN 500000 AND 1999999
ORDER BY FEE DESC
, CAR_TYPE
, CAR_ID DESC
문제에 기재된 FEE 값이 50만원 이상 200만원 미만인 데이터를 뽑기 위해
상기 쿼리를 서브쿼리로 넣어주고, 조회 조건 및 정렬 조건을 추가하여 문제를 해결했다.
리뷰
코드에서는 FEE 값을 (DAILY_FEE - (DAILY_FEE * 0.08)) * 30 과 같이 0.08 같은 상수를 곱하여
계산하고 있는데 장기적으로 봤을 때 위와 같이 작성하는건 좋지 않다고 생각한다.
할인율은 변동이 있을수도 있는 컬럼이기 때문에
CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블도
같이 조인해서 CAR_TYPE에 따라 DISCOUNT_RATE를 곱해주는게 올바른 거 같다.
최종
SELECT *
FROM (
SELECT A.CAR_ID
, A.CAR_TYPE
, 30 * A.DAILY_FEE * (1 - (B.DISCOUNT_RATE * 0.01)) AS FEE
FROM CAR_RENTAL_COMPANY_CAR A
, CAR_RENTAL_COMPANY_DISCOUNT_PLAN B
WHERE A.CAR_TYPE = B.CAR_TYPE
AND B.DURATION_TYPE = '30일 이상'
AND A.CAR_TYPE IN ('세단', 'SUV')
AND A.CAR_ID NOT IN (
SELECT A.CAR_ID
FROM CAR_RENTAL_COMPANY_CAR A
, CAR_RENTAL_COMPANY_RENTAL_HISTORY B
WHERE A.CAR_ID = B.CAR_ID
AND A.CAR_TYPE IN ('세단', 'SUV')
AND TO_CHAR(B.END_DATE, 'YYYYMMDD') >= '20221101'
AND TO_CHAR(B.START_DATE, 'YYYYMMDD') < '20221201'
)
) A
WHERE A.FEE BETWEEN 500000 AND 1999999
ORDER BY FEE DESC
, CAR_TYPE
, CAR_ID DESC