본문 바로가기

Skill Sets/SQL

[SQL] 대여 기록이 존재하는 자동차 리스트 구하기(프로그래머스/MySQL/Level 3)

SMALL

안녕하세요! 데코입니다!

오늘은 프로그래머스 코딩테스트 연습에 있는 "대여 기록이 존재하는 자동차 리스트 구하기" 문제를 포스팅하려고 합니다!

 

바로 포스팅 시작할게요! :)

(출처 : https://school.programmers.co.kr/learn/courses/30/lessons/157341)

1. 문제 : 대여 기록이 존재하는 자동차 리스트 구하기(Lv. 3)

 


 

2. 문제 설명

 

다음은 어느 자동차 대여 회사에서 대여 중인 자동차들의 정보를 담은 CAR_RENTAL_COMPANY_CAR 테이블과
자동차 대여 기록 정보를 담은 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블입니다.
CAR_RENTAL_COMPANY_CAR 테이블은 아래와 같은 구조로 되어있으며,
CAR_ID, CAR_TYPE, DAILY_FEE, OPTIONS는 각각
자동차 ID, 자동차 종류, 일일 대여 요금(원), 자동차 옵션 리스트를 나타냅니다.

 

[ 테이블 구조 ]

 

COLUMN NAME TYPE NULLABLE
CAR_ID INTEGER FALSE
CAR_TYPE VARCHAR(255) FALSE
DAILY_FEE INTEGER FALSE
OPTIONS VARCHAR(255) FALSE

 

자동차 종류는 '세단', 'SUV', '승합차', '트럭', '리무진'이 있습니다.
자동차 옵션 리스트는

콤마(',')로 구분된 키워드 리스트(옵션 리스트 값 예시: '열선시트', '스마트키', '주차감지센서')로 되어있으며,
키워드 종류는 '주차감지센서', '스마트키', '네비게이션', '통풍시트', '열선시트', '후방카메라', '가죽시트'가 있습니다.

 

CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블은 아래와 같은 구조로 되어있으며,
HISTORY_ID, CAR_ID, START_DATE, END_DATE 는 각각
자동차 대여 기록 ID, 자동차 ID, 대여 시작일, 대여 종료일을 나타냅니다.

 

COLUMN NAME TYPE NULLABLE
HISTORY_ID INTEGER FALSE
CAR_TYPE INTEGER FALSE
START_DATE DATE FALSE
END_DATE DATE FALSE

 

[ 문제 ]

 

CAR_RENTAL_COMPANY_CAR 테이블과
CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서
자동차 종류가 '세단'인 자동차들 중
10월에 대여를 시작한 기록이 있는 자동차 ID 리스트를 출력하는 SQL문을 작성해 주세요.
자동차 ID 리스트는 중복이 없어야 하며, 자동차 ID를 기준으로 내림차순 정렬해 주세요.

 

[ 예시 ]

 

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

 

CAR_ID CAR_TYPE DAILY_FEE OPTIONS
1 세단 16000 가죽시트,열선시트,후방카메라
2 SUV 14000 스마트키,네비게이션,열선시트
3 세단 22000 주차감지센서,후방카메라, 가죽시트
4 세단 12000 주차감지센서

 

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

 

HISTORY_ID CAR_ID START_DATE END_DATE
1 4 2022-09-27 2022-09-27
2 3 2022-10-03 2022-10-04
3 2 2022-10-05 2022-10-05
4 1 2022-10-11 2022-10-14
5 3 2022-10-13 2022-10-15

 

10월에 대여를 시작한 기록이 있는 '세단' 종류의 자동차는 자동차 ID가 1, 3 인 자동차이고, 

자동차 ID를 기준으로 내림차순 정렬하면 다음과 같이 나와야 합니다.

 

[ 출력 결과 ]

CAR_ID
3
1

 


 

3. 문제 풀이

# 1안
SELECT  DISTINCT(A.CAR_ID)
  FROM  CAR_RENTAL_COMPANY_RENTAL_HISTORY  A
  LEFT
  JOIN  CAR_RENTAL_COMPANY_CAR  B
    ON  A.CAR_ID = B.CAR_ID
 WHERE  B.CAR_TYPE = '세단'
        AND SUBSTR(A.START_DATE,6,2) = 10
 ORDER
    BY  A.CAR_ID DESC

 

이번 문제는 1안 한 가지로 작성했습니다!

#  1안 풀이 설명

# [ 문제 접근 설명 ]


문제를 읽고 조건에 맞는 쿼리를 작성하기 위해서 다음과 같이  다섯 가지 단계로 진행했어요!

1. CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과 CAR_RENTAL_COMPANY_CAR 테이블을 조인하기(JOIN)
2. CAR_RENTAL_COMPANY_CAR 테이블의 CAR_TYPE 컬럼이 '세단'인 CAR_ID를 선택(WHERE)
3. 10월인 렌탈 이력이 있는 데이터 필터링
4. CAR_ID 중복 제거

5. CAR_ID 기준으로 내림차순 정렬

 

 

# [ 1안 쿼리 작성 설명 ]

먼저 첫 번째 단계에서는 어느 테이블을 기준으로 JOIN을 할지 파악해 보았어요!

 

CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 CAR_RENTAL_COMPANY_CAR 테이블을

 

LEFT JOIN으로 조인을 실행해 주었어요! 

 

기준은 두 테이블에서 CAR_ID가 동일한 컬럼과 값을 가지고 있어서 CAR_ID로 이용했습니다! 

SELECT  DISTINCT(A.CAR_ID)
    FROM  CAR_RENTAL_COMPANY_RENTAL_HISTORY A
     LEFT  JOIN CAR_RENTAL_COMPANY_CAR B
         ON   A.CAR_ID = B.CAR_ID
WHERE  B.CAR_TYPE = '세단'
               AND SUBSTR(A.START_DATE,6,2) = 10
 ORDER
          BY  A.CAR_ID DESC

 

두 번째 작업은 WHERE절에서 CAR_ID가 '세단'인 데이터만 조회가 되도록

 

조건 필터링을 걸어주었습니다!

 

WHERE  B.CAR_TYPE = '세단'

 

세 번째 작업은 WHERE절에서 10월인 렌탈 이력이 있는 데이터만 조회가 되도록 조건을 추가했어요!

 

SUBSTR(A.START_DATE,6,2)을 이용해서 '월' 정보만을 가져온 다음에 이 내역이 10인 데이터만 가져오도록 

 

조건 필터링을 걸어주었습니다!

 

WHERE  B.CAR_TYPE = '세단'
                AND SUBSTR(A.START_DATE,6,2) = 10

 

네 번째 작업은 두 조건을 만족하는 CAR_ID가 중복으로 나오지 않도록

 

SELECT절에 DISTINCT() 함수를 이용해서, 해당하는 CAR_ID가 유일하게 나오도록 작성했습니다!

 

SELECT  DISTINCT(A.CAR_ID)

 

마지막으로는 CAR_ID 컬럼을 기준으로 내림차순 정렬했어요!

ORDER BY절을 사용하고, CAR_ID 컬럼을 기준으로 내림차순(DESC)으로 정렬하면 됩니다!

 

정답...!


 

4. 데코의 문제 풀이 후기

이번 문제는 LEFT JOIN, SUBSTR 함수, DISINTCT 함수를 이용해서 요구사항에 맞게 쿼리를 작성하는 문제예요!

이제는 이전 포스팅에서 사용한 적이 있는 함수들을 이용해서 쿼리를 작성하고 있네요!

테이블의 구조를 파악하고 문제의 요구사항에 맞게 쿼리를 작성하면 됩니다!

 

쿼리를 작성해 보면 감이 오실 거예요!

 

테이블에 따라 JOIN 대신 서브쿼리를 써도 될 것으로 보이는데...! 

 

상황에 따라 더 효율적인 쿼리를 달라질 수 있다는 부분도 말씀드릴게요!

 



이번 문제는 LEFT JOIN, SUBSTR 함수, DISINTCT 함수 등을 이용하여

요구사항에 맞게 쿼리를 작성해 보았습니다!

설명이 어려운 부분 혹은 잘 이해가 안 가는 부분

그리고 더 궁금한 내용이 있다면

언제든지 댓글로 남겨주세요!

빠르게 궁금증을 해결해 드릴게요!

공감과 댓글은 큰 힘이 됩니다!

오늘도 블로그 방문해 주시고

포스팅 읽어주셔서 감사합니다!

LIST