상세 컨텐츠

본문 제목

[ 프로그래머스 / SQL KIT / MySQL ] 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기

알고리즘/프로그래머스

by 감싹이 2023. 1. 13. 10:14

본문

🎉 문제

CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 대여 시작일을 기준으로 2022년 8월부터 2022년 10월까지 총 대여 횟수가 5회 이상인 자동차들에 대해서 해당 기간 동안의 월별 자동차 ID 별 총 대여 횟수(컬럼명: RECORDS) 리스트를 출력하는 SQL문을 작성해주세요. 결과는 월을 기준으로 오름차순 정렬하고, 월이 같다면 자동차 ID를 기준으로 내림차순 정렬해주세요. 특정 월의 총 대여 횟수가 0인 경우에는 결과에서 제외해주세요.

 

🎉 풀이

WHERE 절에서 CAR_ID 를 필터링 하기 위한 서브쿼리를 작성해야 하는 게 핵심인 문제 같다..

사실 나도 대충 풀었을 땐 서브쿼리를 이용해야한다는 생각을 떠올리지 못했는데 질문하기를 보고 무릎을 쳤다 

SQL 공부 더 열심히 해야지

 

아무튼 서브쿼리를 작성한다. 난 서브쿼리 문제를 풀 때 항상 서브쿼리를 먼저 작성함..

8월에서 10월까지 총 대여횟수가 5회 이상인 CAR_ID를 뽑는 쿼리 작성

SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE MONTH(START_DATE) BETWEEN 8 AND 10
GROUP BY CAR_ID
HAVING COUNT(*)>=5

결과로 8월에서 10월까지 각 달별로 5회 이상 대여한 자동차 리스트가 뽑힌다

이제 외부쿼리를 작성해보자

먼저 8월에서 10월까지 대여한 자동차 목록을 뽑는 쿼리를 작성한다

SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(*) AS RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE (MONTH(START_DATE) BETWEEN 8 AND 10)

CAR_ID에 있는 조건을 작성한다. 단, 서브쿼리의 종류가 다중행 서브쿼리이므로 부등호는 사용할 수 없고 다중행 연산자를 사용해줘야 한다

다중행 연산자
IN : 메인쿼리의 비교 조건이 서브쿼리 결과 중에서 하나라도 일치하면 참
ANY, SOME : 메인쿼리의 비교 조건이 서브쿼리의 결과와 하나 이상 일치하면 참
ALL : 메인쿼리의 비교 조건이 서브쿼리의 검색 결과와 모두 일치하면 참
EXIST : 메인 쿼리의 비교 조건이 서브쿼리의 결과 중 만족하는 값이 하나라도 존재하면 참
SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(*) 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(*)>=5
)

이제 COUNT를 위한 GROUP BY절을 작성해주는데 MONTH와 CAR_ID 두 개의 속성으로 그룹화해준다(각 MONTH 별로 CAR_ID를 구분할 예정이므로..)

+ GROUP BY를 사용하려면 SELECT 절에도 GROUP BY에 활용한 속성들을 적어주어야 한다

SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(*) 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(*)>=5
)
GROUP BY MONTH(START_DATE), CAR_ID

문제에 나온대로 월별로 먼저 오름차순 정렬한 후, 같은 월인 레코드들은 CAR_ID 기준으로 내림차순 정렬을 한 번 더 수행해준다

+ ORDER BY 는 작성된 컬럼 순서대로 정렬 기준이 되며 ASC는 오름차순, DESC 는 내림차순이다

 

 

🎉완성 코드

SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(*) 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(*)>=5
)
GROUP BY MONTH(START_DATE), CAR_ID
ORDER BY MONTH(START_DATE) ASC, CAR_ID DESC

 

 

더보기

사담..

아무리 구글링해도 답이 안 나오길래 다시 봤더니 새로 등록된 문제였다.

39명 완료라니..

오늘 스터디 가서 다같이 풀어봐야겠다.

 

관련글 더보기