지난 토요일에 풀려다가 막혀서 한동안 묵혀두고 있던 문제가 깔끔하게 풀렸다. 질문게시판에 질문도 드렸었고 다른 분들이 도와주시긴 했지만, 한 번이라도 내 스스로의 힘으로 이해하고 직접 쿼리를 쳐 보는 게 가장 정확하다는 걸 실감한 짜릿한 경험.
그리고 풀다가 막히면 그거 해결하겠다고 몇 시간씩 끙끙대는 것보단 잠깐 다른 일부터 먼저 하면서 머리를 식히는 게 내 경험상 더 나은 것 같다. 시간을 효율적으로 쓰게 만들어준다는 장점도 있고, 두뇌 풀가동의 지속시간이 그렇게까지 길지 않은 것 같아서. 아예 포기하고 내던져버리지만 않는 게 중요한 듯.
SQL 코드카타 59번
1. 2022년 10월 16일을 기준으로 자동차들의 대여가능 여부를 구분하고
2. car_id별로 내림차순 정렬하는 문제
문제에서 요구하는 조건 자체는 그렇게 복잡하지 않은데, 내가 애를 먹었던 부분은 1번을 어떻게 처리할지였다. 어떤 값들이 어떤 식으로 들어가 있는지 확인하기 위해 전체 테이블을 조회해 봤다.
select * from CAR_RENTAL_COMPANY_RENTAL_HISTORY
order by car_id
이런 결과가 나온다. 스크롤을 내려서 다른 데이터들을 좀 살펴보면,
이 문제에서는 2022년 10월 16일을 기준으로 대여가능 여부를 판별해야 한다. car_id 2번의 경우는 대여 기록이 여러 건 있지만, 10/16에 걸리는 경우가 하나 있으므로(history_id 685번) '대여중'으로 표시되어야 한다. 반면, car_id 3번의 경우 대여 기록이 여러 건 있긴 하지만 애초에 시작 날짜가 10/16 이후이므로 10/16 시점에서는 '대여 가능' 상태다. 즉, car_id별 총 대여 기록이 몇 건이든간에
처음에 막혔던 부분은 '결국 문제에서 원하는 답을 출력하기 위해서는 car_id 별로 그루핑을 해 줘야 하는데, 이 때 불필요한 데이터들(car_id 2번으로 치면, 대여가능 여부를 판별하기 위해 필요한 history_id 685번을 제외한 다른 데이터들)을 어떻게 떨궈야 할지' 였다.
우선 확실하게 대여중으로 판별되어야 하는 경우는
select car_id
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
where '2022-10-16' between start_date and end_date
order by car_id
이다. 그리고 이 결과를 서브쿼리로 처리해서 원래 테이블과 한 번 더 left join해 주었다.
select *
from CAR_RENTAL_COMPANY_RENTAL_HISTORY h
left join
(
select car_id
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
where '2022-10-16' between start_date and end_date
order by car_id
) a
on h.car_id = a.car_id
order by h.car_id
결과는 이렇게 나온다.
대여가 가능한 경우는 left join한 결과 a.car_id와 매칭되는 값이 없는 경우다. 예컨대 car_id 15번의 경우, '10/16 기준으로 확실하게 '대여중' 상태를 판별해 주는 서브쿼리'와 조인했을 때 매칭되는 값이 없다. 즉, car_id 15번은 '대여 가능' 그룹이다.
여기까지만 해결된다면 문제에서 요구하는 나머지 조건들은 기본적인 쿼리 문법을 활용해 충족시켜주면 된다.
select h.car_id,
case when a.car_id is null then '대여 가능'
else '대여중' end as 'AVAILABILITY'
from CAR_RENTAL_COMPANY_RENTAL_HISTORY h
left join
(
select car_id
from CAR_RENTAL_COMPANY_RENTAL_HISTORY
where '2022-10-16' between start_date and end_date
) a
on h.car_id = a.car_id
group by 1
order by 1 desc;
한 정답 코드. 실행 결과는 아래와 같다.
아마 이것보다 더 간단하게 해결하는 방법도 있을 텐데, 나중에 따로 풀어보고 별도의 포스팅으로 기록할 예정.
이게 뭐라고 이렇게 뿌듯한지..ㅎㅎ