본문 바로가기
SQL 문제 풀기/1. 프로그래머스 SQL : 2023.12.17~2024.2.29

<프로그래머스 47> 자동차 평균 대여 기간 구하기(Lv.2)

by HYEHYE_SON 2024. 2. 1.
728x90

 

프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지


 

문제 설명

다음은 어느 자동차 대여 회사의 자동차 대여 기록 정보를 담은 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블입니다. CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블은 아래와 같은 구조로 되어있으며, HISTORY_IDCAR_IDSTART_DATEEND_DATE 는 각각 자동차 대여 기록 ID, 자동차 ID, 대여 시작일, 대여 종료일을 나타냅니다.

 

Column name Type Nullable
HISTORY_ID INTEGER FALSE
CAR_ID INTEGER FALSE
START_DATE DATE FALSE
END_DATE DATE FALSE

 


문제

CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 평균 대여 기간이 7일 이상인 자동차들의 자동차 ID와 평균 대여 기간(컬럼명: AVERAGE_DURATION) 리스트를 출력하는 SQL문을 작성해주세요. 평균 대여 기간은 소수점 두번째 자리에서 반올림하고, 결과는 평균 대여 기간을 기준으로 내림차순 정렬해주시고, 평균 대여 기간이 같으면 자동차 ID를 기준으로 내림차순 정렬해주세요.

예시

예를 들어 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블이 다음과 같다면

HISTORY_ID CAR_ID START_DATE END_DATE
1 1 2022-09-27 2022-10-01
2 1 2022-10-03 2022-11-04
3 2 2022-09-05 2022-09-05
4 2 2022-09-08 2022-09-10
5 3 2022-09-16 2022-10-15
6 1 2022-11-07 2022-12-06

 

자동차 별 평균 대여 기간은

  • 자동차 ID가 1인 자동차의 경우, 대여 기간이 각각 5일, 33일, 30일인 기록이 존재하므로 평균 22.7일
  • 자동차 ID가 2인 자동차의 경우, 대여 기간이 각각 1일, 3일인 기록이 존재하므로 평균 2일
  • 자동차 ID가 3인 자동차의 경우, 대여 기간이 30일인 기록만 존재하므로 평균 30일 입니다. 평균 대여 기간이 7일 이상인 자동차는 자동차 ID가 1, 3인 자동차이고, 평균 대여 기간 내림차순 및 자동차 ID를 기준으로 내림차순 정렬하면 다음과 같이 나와야 합니다.
CAR_ID AVERAGE_DURATION
3 30.0
1 22.7

1. 오라클 정답

select car_id, average_duration
    from (select car_id, round(avg((end_date - start_date) + 1 ),1) average_duration
            from car_rental_company_rental_history
            group by car_id) j
    where average_duration >= 7
    order by average_duration desc, car_id desc;

((이하생략))

 

 

오라클 해설해보기

여기서는 서브쿼리를 사용해줘야한다. 
서브쿼리를 from절에 사용해야 하는데, 이를 IN LINE VIEW라고 부른다.


# 1. SELECT 절
출력해야할 컬럼명(car_id, average_duration)을 나열해준다. 


# 2. FROM 절
FROM절에서 서브쿼리를 사용한다.

서브쿼리를 사용하는 이유는 car_id별 평균 대여기간을 구하기 위함이다.
평균 대여기간을 구해서 출력된 결과 값을 사용하여 
메인쿼리에서 대여기간이 7일 이상인 자동차들을 조건을 줘야 한다. 

따라서 평균 대여기간을 구하는 것이 중요한데,
구하기 위해서는 group by를 사용해 car_id를 묶어준 후 
car_id 별 대여기간을 합산 후 평균을 출력할 수 있게 된다.

■ 평균 대여 기간(average_duration)을 구하려면?
(대여 종료일 - 대여시작일 + 1) 을 해주어 대여 기간을 구한 후 
AVG() 함수로 평균 대여기간을 구해주면 된다. 
이때 + 1을 해준 이유는 예시와 같이 대여종료일을 포함한 날짜여야 하기 때문이다. 

추가적으로 평균 대여 기간을 소수점 두번째 자리에서 반올림 해야하는
조건이 있기 때문에 round()함수를 사용해준다.

-- round( 컬럼명, 소수점 이하 출력될 자리 수 )
=> 즉, 1이면 소수점 두번째 자리에서 반올림된 후
소수점 1의 자리까지 출력된다.

최종 in line view의 select절은 아래와 같다.
select car_id, round(avg((end_date - start_date) + 1 ),1) average_duration


# 3. WHERE 절
평균 대여기간을 구해서 출력된 결과 값을 사용하여 
메인쿼리에서 대여기간이 7일 이상인 자동차들을 조건을 충족시켜준다.
( 주의할 점은 average_duration > 6 을 사용하면, 
평균 대여기간이 6.8인 데이터도 출력되기 때문에 >= 7을 사용해줘야한다)

where average_duration >= 7


# 4. ORDER BY 절
평균대여기간(average_duration)을 기준으로 내림차순 정렬(desc)해주고, 
평균 대여기간이 같으면 자동차id(car_id)를 기준으로 내림차순 정렬(desc)해준다.


 

2. MySQL 정답

select car_id, average_duration
    from (select car_id, round(avg(datediff(end_date, start_date) + 1 ),1) average_duration
            from car_rental_company_rental_history
            group by car_id) j
    where average_duration >= 7
    order by average_duration desc, car_id desc;

((이하생략))

 

 

MySQL 해설해보기

오라클과 해설은 같으나 
대여기간을 구할 때 대여종료일에서 대여 시작일의 차를 구하는 작업에서 차이가 발생한다.

대여 기간은 대여 종료일에서 대여 시작일을 빼면 구할 수 있다.

 MySQL은 오라클과 다르게 마이너스(-)연산자로 날짜 연산을 하기 어렵다.
두 날짜 사이의 차를 알기 위해서는  DATEDIFF 함수를 사용하여 계산해야한다.

 * DATEDIFF( A, B )
   : A와 B 두 날짜의 차이를 구하기 위한 함수로
     A에서 B를 뺀다. (A - B)
    
따라서 DATEDIFF( END_DATE, START_DATE) 를 해주며,

마이너스 연산을 하였을 때,
대여 종료일의 날짜는 포함되지 않고 계산되고 있다.

예시를 보면,
---------------
car_id 1,
start_date : 2022-09-27,
end_date : 2022-10-01
----------------
위와 같은 데이터가 있을 때 
대여기간이 5일이다. 

따라서 +1을 해주어서 대여 기간을 구해주어야 한다.

 

 

 

출처 : 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges

반응형