


자동차 대여 시작일 기준(start_date)
2022년 8월부터 2022년 10월까지 대여 횟수가 5회 이상
기간 동안의 월별 자동차 ID 별 총 대여 횟수(컬럼명: RECORDS) 리스트를 출력
월을 기준으로 오름차순 정렬하고, 월이 같다면 자동차 ID를 기준으로 내림차순 정렬
우선, 대여 시작일 기준 월별 값을 추가해주기 위해서 다음과 같이 MONTH() 함수를 사용해줍니다.
MONTH(start_date) month
그 다음으로 08월부터 10월까지 대여 횟수를 확인해줘야 합니다.
month BETWEEN 8 AND 10;
그리고, 월별 & 자동차 ID 별 그룹화를 위해 Group By 절에 month, car_id를 추가해줍니다.
GROUP BY month, car_id
그 다음으로 대여 횟수 5회를 필터링하려고 해보니, 현재 쿼리에서는 month와 car_id가 함께 그룹화가 되어 있기 때문에 car_id만을 기준으로 전체 횟수(count)가 5회 이상인지 여부를 확인할 수 없습니다.
따라서, 이를 확인하기 위한 서브쿼리를 활용해줍니다.
SELECT car_id
FROM car_rental_company_rental_history
GROUP BY car_id
HAVING COUNT(car_id) >= 5
위와 같이 서브쿼리가 작성되었습니다. 이제 여기서 정렬만 해주면 끝날 것 같지만, 사실 한가지 추가로 고려해야 할 것이 있습니다.
서브 쿼리 내에서 count 되는 횟수는 car_id를 기준으로 카운팅 됩니다. 만약에 8월 또는 10월 외에 다른 달에서 렌트한 기록이 횟수로 포함되면, 의도치 않은 값까지 함께 조회 될 수 있습니다.
따라서, WHERE 절을 통해 이를 걸러줍니다.
WHERE MONTH(start_date) BETWEEN 8 AND 10
마지막으로 정렬을 추가해줍니다.
ORDER BY month, car_id DESC;
SELECT
MONTH(start_date) month,
car_id,
COUNT(history_id) records
FROM car_rental_company_rental_history
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
)
GROUP BY month, car_id
HAVING month BETWEEN 8 AND 10
ORDER BY month, car_id DESC;
해당 문제를 해결하면서 쿼리 실행 흐름 관련 의문이 생겼습니다.
분명, 내가 알고 있는 쿼리 실행 flow는 다음과 같습니다.
FROM clause -> WHERE clause -> GROUP BY clause -> HAVING clause -> SELECT clause -> ORDER BY clause
하지만, 위 쿼리를 보면 SELECT 절에서 추가된 alias를 GROUP BY 또는 HAVING 절에서 사용이 가능한 것을 알 수 있습니다.
이와 관련된 블로그 글들을 찾아보던 중 StackOverFlow 에서 필자와 같은 고민을 하는 사람의 글을 확인할 수 있었습니다.
이에 대한 답변 중 이런 댓글이 있었습니다.
However, In MySQL is different. MySQL extends standard SQL behavior to permit the use of an alias in the HAVING clause for the aggregated column.
MySQL에서는 SELECT 절에서 정의된 별칭을 HAVING 절에서 사용할 수 있도록 허용합니다.
이와 관련된 공식문서도 참조되어 있어 공식문서 내용을 확인해봤습니다.

위처럼 MySQL의 확장 기능 중 HAVING 절에서 별칭을 허용한다고 명시되어 있습니다.
이와 같이 쿼리 실행 순서와 상관없이 SELECT 절에서 사용한 별칭을 GROUP BY, HAVING에서도 사용이 가능하다 라는 점을 알 수 있었습니다.