코딩테스트/SQL

SQL > 프로그래머스 151139 [level 3] 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기

Porits789 2024. 6. 27. 13:19

풀이 위주로 작성하는 방식으로 변경합니다.

문제

https://school.programmers.co.kr/learn/courses/30/lessons/151139

 

프로그래머스

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

programmers.co.kr

[문제 포인트 짚기]

테이블에서 대여 시작일을 기준으로 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서

해당 기간 동안의 월별 자동차 ID 별 총 대여 횟수(칼럼명: RECORDS) 리스트를 출력하는 SQL문을 작성해 주세요.

결과는 월을 기준으로 오름차순 정렬하고, 월이 같다면 자동차 ID를 기준으로 내림차순 정렬해 주세요.

특정 월의 총 대여 횟수가 0인 경우에는 결과에서 제외해 주세요.

 

  • 대여 시작일 기준
    : START_DATE만 조건으로 사용한다는 의미! END_DATE는 고려할 필요가 없다.
  • 2022 8월부터 2022 10월까지 & 총 대여 횟수가 5회 이상
    : 각 차량의 ID 별로 8~10월 사이의 대여 횟수를 체크해서 조건으로 사용해야 한다.
  • 월별 자동차 ID별 총 대여 횟수
    : 자동차의 ID 별 총 대여 횟수를 계산해야 하는데 월별로 나누어서 계산해야 한다. 예제의 결과를 보면 이해할 수 있다.

예제 결과

풀이

1. 원하는 날짜의 데이터만 가져오기.

우리가 원하는 날짜는 2022-8월 ~ 2022-10월까지의 데이터이다.

프로그래머스의 테스트케이스에서는 2022년도의 데이터만 가지고 있다. 따라서 연도를 비교할필요는 없다...

그래서 조건에 이런 조건도 가능한다.

WHERE MONTH(start_date) BETWEEN '8' AND '10'

 

하지만 년도까지 따지는 꼼꼼함을 갖춰보자. 다음과 같이 임시테이블로 조건에 맞는 값들을 생성할 수 있다.

WITH CTE AS (
    SELECT CAR_ID, MONTH(start_date) as mm
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE start_date BETWEEN '2022-08-01' AND '2022-10-31'
)

 

조건에 년도를 따져주면 다른 년도에 대해서 걱정할 필요가 없다! 결과는 이런 식이다.

 
CAR_ID mm
15 8
26 8
27 8
29 8

 

2. 총 대여 횟수가 5회 이상인 자동차의 ID를 찾기

CTE에서 8~10월까지의 데이터만을 가져왔다. 이를 활용해서 총 대여 횟수를 구하면 된다. COUNT를 사용하자.

CTE2 AS (
    SELECT car_id, COUNT(car_id) as c
    FROM CTE
    GROUP BY car_id
)

자 CTE2를 CTE와 JOIN할떄 c>=5로 조건을 걸면 총 대여 횟수가 5회 이상인 자동차들만 남게 된다.

CTE3 AS (
    SELECT c.car_id, mm
    FROM CTE c JOIN CTE2 c2
        ON c2.c >=5 AND c2.car_id = c.car_id
)
CAR_ID mm
15 8
27 8
13 8
28 8

 

3. 월별 자동차 ID별 총 대여 횟수

월별, 자동차의 ID 별 총 대여 횟수를 계산한다. 그리고 출력값에 맞춰서 칼럼의 이름을 변경해 주고 정렬까지 잊지 않으면 완성이다.

WITH CTE AS (
    SELECT CAR_ID, MONTH(start_date) as mm
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE start_date BETWEEN '2022-08-01' AND '2022-10-31'
), CTE2 AS (
    SELECT car_id, COUNT(car_id) as c
    FROM CTE
    GROUP BY car_id
), CTE3 AS (
    SELECT c.car_id, mm
    FROM CTE c JOIN CTE2 c2
        ON c2.c >=5 AND c2.car_id = c.car_id
)
SELECT mm as MONTH ,car_id as CAR_ID, COUNT(car_id) as RECORDS
FROM CTE3
GROUP BY car_id,mm
ORDER BY mm, CAR_ID DESC

 

GROUP BY 시에 자동차 아이디별로 우선 묶어야 하기 때문에 car_id가 앞에 들어간다.