데이터베이스/ORACLE

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

썬키 2024. 6. 3. 13:10

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

링크를 클릭하면 해당 문제로 이동합니다.

 

출처 - 프로그래머스

 


 

접근하기

 

 

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';

 

문제를 풀면서 제일 많이 고민 되었던 부분이

어떻게하면 문제에 기재된 기간 내에 대여 가능한 차량 데이터를 추출할 수 있을까였는데

위와 같이 작성하고 상기 쿼리에서 추출된 데이터를 제외하면 되겠다.

 

CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블 내 데이터

 

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