코딩테스트 - 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기 (프로그래머스) MySQL
코딩테스트 연습에 공개된 문제는 (주)그렙이 저작권을 가지고 있습니다.
(지문 하단에 별도 저작권 표시 문제 제외)
코딩테스트 연습 문제의 지문, 테스트케이스, 풀이 등과 같은 정보는 비상업적, 비영리적 용도로 게시할 수 있습니다.
문제 정보
- 프로그래머스
- MySQL
- level 3
- 점수 : 해당 없음
- 문제 링크
문제
다음은 어느 자동차 대여 회사의 자동차 대여 기록 정보를 담은 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년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서 해당 기간 동안의 월별 자동차 ID 별 총 대여 횟수(컬럼명: RECORDS) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 월을 기준으로 오름차순 정렬하고, 월이 같다면 자동차 ID를 기준으로 내림차순 정렬해주세요. 특정 월의 총 대여 횟수가 0인 경우에는 결과에서 제외해주세요.
입출력 예
예를 들어 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블이 다음과 같다면
| HISTORY_ID | CAR_ID | START_DATE | END_DATE |
|---|---|---|---|
| 1 | 1 | 2022-07-27 | 2022-08-02 |
| 2 | 1 | 2022-08-03 | 2022-08-04 |
| 3 | 2 | 2022-08-05 | 2022-08-05 |
| 4 | 2 | 2022-08-09 | 2022-08-12 |
| 5 | 3 | 2022-09-16 | 2022-10-15 |
| 6 | 1 | 2022-08-24 | 2022-08-30 |
| 7 | 3 | 2022-10-16 | 2022-10-19 |
| 8 | 1 | 2022-09-03 | 2022-09-07 |
| 9 | 1 | 2022-09-18 | 2022-09-19 |
| 10 | 2 | 2022-09-08 | 2022-09-10 |
| 11 | 2 | 2022-10-16 | 2022-10-19 |
| 12 | 1 | 2022-09-29 | 2022-10-06 |
| 13 | 2 | 2022-10-30 | 2022-11-01 |
| 14 | 2 | 2022-11-05 | 2022-11-05 |
| 15 | 3 | 2022-11-11 | 2022-11-11 |
대여 시작일을 기준으로 총 대여 횟수가 5회 이상인 자동차는 자동차 ID가 1, 2인 자동차입니다. 월 별 자동차 ID별 총 대여 횟수를 구하고 월 오름차순, 자동차 ID 내림차순으로 정렬하면 다음과 같이 나와야 합니다.
| MONTH | CAR_ID | RECORDS |
|---|---|---|
| 8 | 2 | 2 |
| 8 | 1 | 2 |
| 9 | 2 | 1 |
| 9 | 1 | 3 |
| 10 | 2 | 2 |
풀이 코드
풀이 코드
1
2
3
4
5
6
7
8
9
10
11
12
SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(CAR_ID) AS RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) BETWEEN 8 AND 10 AND
CAR_ID IN (
SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) BETWEEN 8 AND 10
GROUP BY CAR_ID
HAVING COUNT(CAR_ID) >= 5
)
GROUP BY MONTH(START_DATE), CAR_ID
ORDER BY MONTH(START_DATE) ASC, CAR_ID DESC;
풀이 방식
아래 네 단계로 풀이를 진행했다.
(1) 무엇을 반환해야 하는가
(2) 어떠한 데이터 뭉치에서 데이터를 조회해야 하는가
(3) 어떤 조건의 데이터를 가져와야 하는가
(4) 가져온 데이터를 어떻게 표현해야 하는가
(1) 무엇을 반환해야 하는가
1
2
-- 대여시작월, CAR_ID, 판매수량을 반환해야 한다.
SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(CAR_ID) AS RECORDS
(2) 어떠한 데이터 뭉치에서 데이터를 조회해야 하는가
1
2
-- CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 가져와야 한다.
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
(3) 어떤 조건의 데이터를 가져와야 하는가
1
2
3
4
5
6
7
8
9
10
11
12
-- (1) 대여 시작일이 8월 ~ 10월 사이여야 한다.
WHERE MONTH(START_DATE) BETWEEN 8 AND 10
-- (2) 8월 ~ 10월 사이의 대여량이 5개 이상인 CAR_ID여야 한다.
-- 이 부분이 핵심이라고 생각하며, 뒤어세 추가로 다루겠다.
WHERE CAR_ID IN (
SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) BETWEEN 8 AND 10
GROUP BY CAR_ID
HAVING COUNT(CAR_ID) >= 5
)
(4) 가져온 데이터를 어떻게 표현해야 하는가
1
2
3
4
5
-- (1) 월 + CAR_ID 별로 묶어서 보여줘야 한다.
GROUP BY MONTH(START_DATE), CAR_ID
-- (2) 월 오름차순 정렬 + 월이 같다면 자동차 ID 내림차순 정렬
ORDER BY MONTH(START_DATE) ASC, CAR_ID DESC
핵심 풀이 방식
이번 문제의 핵심 풀이 부분은 GROUP BY 보다도 WHERE 절에서 사용하는 서브쿼리라고 생각한다. 월과 CAR_ID를 묶는 것은 간단하나, 8월 ~ 10월 사이의 총 대여량이 5 이상인 차량 이라는 조건을 만족시키기 위해서는 서브쿼리를 사용해야만 하는 것으로 보인다.
조건을 검증하기 위해서는 8월 ~ 10월 동안의 CAR_ID 별 대여량을 알 수 있어야 한다. 이를 위해 서브쿼리로 8 ~ 10월 동안 대여된 CAR_ID 목록을 만들고, 별 가상 테이블을 만들고, HAVING 으로 총 대여량이 5 이상인 것을 거르도록 하였다.
1
2
3
4
5
6
7
8
-- 8월 ~ 10월 동안 대여된 CAR_ID 목록 만들기
SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) BETWEEN 8 AND 10
-- 앞서 만든 목록에서 COUNT 가 5 이상인 CAR_ID 목록 도출
GROUP BY CAR_ID
HAVING COUNT(CAR_ID) >= 5
리뷰
문제의 핵심은 GROUP BY를 익히라는 것 같은데, 오히려 서브쿼리로 풀어가는 방식이 흥미로웠다.
댓글 남기기