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

<프로그래머스 23> 자동차 대여 기록에서 장기/단기 대여 구분하기(Lv.1)

by HYEHYE_SON 2024. 1. 8.
728x90

 

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


 

문제 설명

다음은 어느 자동차 대여 회사의 자동차 대여 기록 정보를 담은 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블입니다. CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블은 아래와 같은 구조로 되어있으며, HISTORY_ID, CAR_ID, START_DATE, END_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 테이블에서 대여 시작일이 2022년 9월에 속하는 대여 기록에 대해서 대여 기간이 30일 이상이면 '장기 대여' 그렇지 않으면 '단기 대여' 로 표시하는 컬럼(컬럼명: RENT_TYPE)을 추가하여 대여기록을 출력하는 SQL문을 작성해주세요. 결과는 대여 기록 ID를 기준으로 내림차순 정렬해주세요.

예시

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

HISTORY_ID CAR_ID START_DATE END_DATE
1 4 2022-09-27 2022-11-27
2 3 2022-10-03 2022-11-04
3 2 2022-09-05 2022-09-05
4 1 2022-09-01 2022-09-30
5 3 2022-09-16 2022-10-15

 

2022년 9월의 대여 기록 중 '장기 대여' 에 해당하는 기록은 대여 기록 ID가 1, 4인 기록이고, '단기 대여' 에 해당하는 기록은 대여 기록 ID가 3, 5 인 기록이므로 대여 기록 ID를 기준으로 내림차순 정렬하면 다음과 같이 나와야 합니다.

HISTORY_ID CAR_ID START_DATE END_DATE RENT_TYPE
5 3 2022-09-16 2022-10-13 단기 대여
4 1 2022-09-01 2022-09-30 장기 대여
3 2 2022-09-05 2022-09-05 단기 대여
1 4 2022-09-27 2022-10-26 장기 대여

 

주의사항

START_DATE와 END_DATE의 경우 예시의 데이트 포맷과 동일해야 정답처리 됩니다.


정답

# 오라클 정답

select history_id, car_id, 
        to_char(start_date, 'rrrr-mm-dd') as start_date,
        to_char(end_date, 'rrrr-mm-dd') as end_date,
        (case when (end_date - start_date)+2 >= 30 then '장기 대여'
        	  else '단기 대여' end ) as rent_type
    from car_rental_company_rental_history
    where to_char(start_date, 'rrrr/mm/dd') = '2022/09'
    order by history_id desc;
 
# MySQL 정답

select history_id, car_id, 
        date_format(start_date, '%Y-%m-%d') as start_date,
        date_format(end_date, '%Y-%m-%d') as end_date,
        ( case when datediff(end_date, start_date) + 2 >= 30 then '장기 대여'
            else '단기 대여' end ) as rent_type
    from car_rental_company_rental_history
    where date_format(start_date, '%Y-%m') = '2022-09'
    order by history_id desc;

 

 

해설해보기

# 1. SELECT 절
출력하고자 하는 컬럼명들 순서대로 나열하는데,
START_DATE와 END_DATE의 DATE FORMAT을 예시와 맞춰주기 위해서
형식 변환이 필요하다. 
( 왜? DATE의 기본 출력 형식이 '년 월 일 시:분:초' 이기 때문에
시:분:초를 출력하지 않기 위해서 형식 변환이 필요한 것 )

   ▶ 오라클 해설
   TO_CHAR([컬럼명], '변경할 데이터 형태')
   위의 함수를 사용해서 날짜형 데이터 형식을 → 문자형 데이터 형식으로 변환한다.

   * 표시한 형태 해석(오라클의 경우 대소문자 구분 없음)
   - RRRR/YYYY : Year 연도 4자리로 표기(ex. 2023, 2024)
   - MM : Month 월 2자리로 표기 (ex. 05, 07)
   - DD : Day 일 2자리로 표기 (ex. 01, 31)

   ▶ MySQL 해설
   날짜형식의 포맷을 지정해주는
   DATE_FORMATE() 함수
   를 이용한다.

   * 표시한 형태 해석(대소문자 구분 있음)
   - %Y : Year 연도를 4자리로 표기 (ex. 2023, 2024)
   - %m : Month 월을 2자리로 표기(ex. 05, 12)
   - %d : Day 일을 두자리로 표기(ex. 04, 28)

   * 참고
   - %c :Month 월을 한 자리로 표기(ex. 5, 12) 
   - %e :Day 일을 한자리로 표기(ex. 4, 28)

# 1-1. SELECT 절의 새로운 컬럼 RENT_TYPE 설명
대여 기간이 30일 이상일 경우 '장기 대여' 
그렇지 않으면 '단기 대여'를 표시하는 컬럼 RENT_TYPE을 
추가해야하는데, 
이럴 때 사용하는 함수가 CASE WHEN 함수이다.

*  CASE WHEN  조건문 설명

   CASE WHEN [조건] THEN [조건이 참일 때 실행할 것]
         ELSE [조건이 거짓일 경우 실행할 것] END
  
  위 문법에 따라 문제에서 원하는 것을 실행하기 위해서는
    ----------------------------------------------------------
    case when 대여기간 >= 30 then '장기 대여'
       else '단기 대여' end as rent_type
    -----------------------------------------------------------
   위와 같이 조건문을 작성해야한다.
   대여기간을 구하는 방법이
   오라클과 mysql 서로 다르기 때문에 
   각각 해설해보도록 하자

 ▶ 오라클 해설
 대여 기간은 대여 종료일에서 대여 시작일을 빼면 구할 수 있다.
오라클에서는 마이너스(-) 연산자 를 사용하여 손 쉽게 연산할 수 있다.
따라서 아래와 같이 구할 수 있는데,

END_DATE - START_DATE 

마이너스 연산을 하였을 때,
대여 시작 날짜와 대여 종료일의 날짜는 포함되지 않고 
계산되기 때문에 +2를 해주어야 한다.


 ▶ MySQL 해설
 대여 기간은 대여 종료일에서 대여 시작일을 빼면 구할 수 있다.
 MySQL은 오라클과 다르게 마이너스(-)연산자로 날짜 연산을 하기 어렵다.
두 날짜 사이의 차를 알기 위해서는 DATEDIFF 함수를 사용하여 계산해야한다.

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

마이너스 연산을 하였을 때,
대여 시작 날짜와 대여 종료일의 날짜는 포함되지 않고 
계산되기 때문에 +2를 해주어야 한다.


# 2. WHERE절
START_DATE가 2022년 9월인 데이터만 출력하기 위해서
TO_CHAR 혹은 DATE_FORMAT함수를 이용해서
데이터의 형식을 바꿔준 후 조건을 입력해준다.


# 3. ORDER BY절
HISTORY_ID를 기준으로 내림차순 정렬(DESC) 해준다.

 

 

결과 출력

((이하 생략))

 

 

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

반응형