[SQL] 프로그래머스 | 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기

·2024년 11월 29일

SQL

목록 보기
2/23

SQL 코드카타 59번

문제

CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블에서 2022년 10월 16일에 대여 중인 자동차인 경우 '대여중' 이라고 표시하고, 대여 중이지 않은 자동차인 경우 '대여 가능'을 표시하는 컬럼(컬럼명: AVAILABILITY)을 추가하여 자동차 ID와 AVAILABILITY 리스트를 출력하는 SQL문을 작성해주세요. 이때 반납 날짜가 2022년 10월 16일인 경우에도 '대여중'으로 표시해주시고 결과는 자동차 ID를 기준으로 내림차순 정렬해주세요.

접근 및 문제

START_DATE, END_DATE를 이용하여 날짜를 필터링 하고 GROUP BY를 이용해 CAR_ID를 그룹화 해야겠다는 생각까지는 어렵지 않게 도달할 것이다. 떠오른대로 우선 아래와 같은 쿼리를 짜보자.

SELECT CAR_ID,
    IF(DATE('2022-10-16') BETWEEN START_DATE AND END_DATE, '대여중', '대여 가능') AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY 1 DESC

여기서 문제에 직면하게 된다. 우리가 이용하는 테이블 'CAR_RENTAL_COMPANY_RENTAL_HISTORY'은 자동차의 모든 대여 기록을 담은 테이블이다. 즉 하나의 차 (CAR_ID)에 대한 여러 개의, 즉 여러 기간의 대여 기록이 있다는 뜻이다. 위 쿼리에서 GROUP BY를 제외하고 돌려보면 아래와 같은 테이블이 나온다.

하나의 CAR_ID 내에서도 AVAILABILITY가 '대여 가능'인 행과 '대여중'인 행이 혼재한다는 의미이다. 이 상황에서 "GROUP BY CAR_ID"를 해버리면 AVAILABILITY에는 어떤 값이 들어가야 하는지 정해진 바가 없기 때문에 임의의 값이 들어가게 되고 틀린 결과값이 나오게 된다.

비슷한 사례 참고

결론 및 코드

그렇다면 어떻게 해결할 수 있을까? 내가 선택한 방법은 MAX()를 이용하는 것이다.

바로 위 테이블을 보면 하나의 CAR_ID에 대해 행이 여러 개 존재하는 것을 알 수 있다. (A) 만약 어느 차가 '2022년 10월 16일'에 '대여 가능'한 상태라면 그 CAR_ID에 대한 모든 AVAILABILITY는 '대여 가능'일 것이다. (B) 반대로 어느 차가 해당 날짜에 '대여중' 상태였다면 해당 날짜가 포함된 하나의 (혹은 여러 개의) 행의 AVAILABILITY는 '대여중'일 것이다.

여기서 이용하라 수 있는 것이 MAX()이다. SQL의 한글 대소비교에 따르면 '대여중'과 '대여 가능'을 대소비교 했을 때 더 큰 것은 '대여중'이다. 즉, 어떤 CAR_ID의 AVAILABILITY에 '대여 가능'만 있다면 MAX()를 취했을 때 '대여 가능'이 반환되겠지만, 하나의 행이라도 '대여중'이라면 MAX()에 의해 '대여중'이 반환될 것이라는 뜻이다.

이를 이용해 정답에 도달하는 쿼리는 아래와 같다.

SELECT CAR_ID,
        MAX(IF(DATE('2022-10-16') BETWEEN START_DATE AND END_DATE, '대여중', '대여 가능')) AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY 1 DESC
profile
To Dare is To Do

0개의 댓글