본문 바로가기
문제풀이/SQL(Oracle)

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

by kime2 2024. 3. 20.

 

문제

https://school.programmers.co.kr/learn/courses/30/lessons/157339#qna

 

프로그래머스

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

programmers.co.kr

CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 자동차 종류가 '세단' 또는 'SUV' 인 자동차 중 2022년 11월 1일부터 2022년 11월 30일까지 대여 가능하고 30일간의 대여 금액이 50만원 이상 200만원 미만인 자동차에 대해서 자동차 ID, 자동차 종류, 대여 금액(컬럼명: FEE) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 대여 금액을 기준으로 내림차순 정렬하고, 대여 금액이 같은 경우 자동차 종류를 기준으로 오름차순 정렬, 자동차 종류까지 같은 경우 자동차 ID를 기준으로 내림차순 정렬해주세요.

 

문제에 대한 해석

-- 조건1: 자동차 종류가 '세단','SUV'
-- 조건2: 2022년 11월 1일부터 2022년 11월 30일까지 대여 가능
-- 조건3: 30일간의 대여 금액 =  50만원 이상 200만원 미만
-- 정렬 :  대여 금액 - 내림차순, 자동차 종류-오름차순, 자동차 ID- 내림차순

 

오답

with ids as (select a.car_id,car_type, daily_fee
from 
(SELECT car_id, car_type, daily_fee, options
from CAR_RENTAL_COMPANY_CAR
where car_type in ('세단','SUV'))a 
join (select HISTORY_ID, CAR_ID, START_DATE, END_DATE
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
where END_DATE < to_date('2022-11-01','YYYY-MM-DD')
or START_DATE > to_date('2022-11-30','YYYY-MM-DD'))b
on a.car_id = b.car_id
group by a.car_id,car_type, daily_fee),
fees as (select car_id,p.car_type, daily_fee*30*(1-discount_rate/100) as fee
from ids join CAR_RENTAL_COMPANY_DISCOUNT_PLAN p
on ids.car_type = p.car_type
where duration_type = '30일 이상')

select car_id,car_type,fee
from fees
where fee between 500000 and 1999999 
order by fee desc, car_type, car_id desc

 

정답

SELECT A.CAR_ID, A.CAR_TYPE, DAILY_FEE*30*(1-B.DISCOUNT_RATE/100) AS FEE 
FROM  CAR_RENTAL_COMPANY_CAR A,
      CAR_RENTAL_COMPANY_DISCOUNT_PLAN B     
WHERE A.CAR_TYPE = B.CAR_TYPE
AND   A.CAR_TYPE IN ('세단','SUV')
AND   B.DURATION_TYPE = '30일 이상'
AND   A.CAR_ID  NOT IN (SELECT C.CAR_ID
                        FROM   CAR_RENTAL_COMPANY_RENTAL_HISTORY C
                        WHERE  '202211' BETWEEN TO_CHAR(START_DATE,'YYYYMM') AND TO_CHAR(END_DATE,'YYYYMM')
                        AND    A.CAR_ID = C.CAR_ID
                       ) #2022년 11월이 START_DATE와 END_DATE 사이에 있지 않는 car_id
AND   (DAILY_FEE*30*(1-B.DISCOUNT_RATE/100)) BETWEEN 500000 AND 2000000-1                         
ORDER BY 3 DESC, 2, 1 DESC

 

작동순서

💡SQL 실행 순서는 From -> Where -> Group by -> Having -> Select -> Order by ->결과반환

 

  1. FROM 절: CAR_RENTAL_COMPANY_CAR와 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 를 CAR_TYPE을 기준으로 조인한 테이블에서
  2. WHERE 절:CAR_TYPE이 '세단' 또는 'SUV'에 포함되고, DURATION_TYPE이 30일 이상이고, DAILY_FEE의 30일 요금에 대해 할인(1-B.DISCOUNT_RATE/100)을 받은 값이 500000 와 2000000-1 사이에 있고,
    1. CAR_RENTAL_COMPANY_RENTAL_HISTORY테이블에서 '202211'이 문자화된 START_DATE와 END_DATE사이에 있지 않는 car_id와 동일
    2. 의 경우에 필터링 하여
  3. SELECT 절:  CAR_ID, CAR_TYPE, FEE를 조회하라
  4. ORDER BY 절: FEE를 기준으로 내림차순, CAR_TYPE기준으로 오름차순, CAR_ID를 기준으로 내림차순