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

문제

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

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


✍️ 문제 요약

  • car_rental_company_rental_history 테이블에서 2022년 10월 16일에 자동차가
  • 대여 중이면 '대여중', 그렇지 않으면 '대여 가능'을 표시하는 컬럼 AVAILABILITY 생성
  • 자동차 ID, AVAILABILITY 출력
  • 반납일이 2022년 10월 16일인 경우도 '대여중'
  • 자동차 ID 내림차순 정렬

✍️ 내가 작성한 코드

SELECT car_id,
       CASE WHEN DATE_FORMAT(start_date, '%Y-%m-%d') <= '2022-10-16' THEN '대여중'
            WHEN DATE_FORMAT(end_date, '%Y-%m-%d') >= '2022-10-16' THEN '대여중'
            ELSE '대여 가능'
            END 'AVAILABILITY'
FROM car_rental_company_rental_history
GROUP BY car_id
ORDER BY car_id DESC;

오답이다! 무엇이 무엇이 문제일까?🤔
🚨 문제점 분석
▶ CASE 조건이 start_date <= '2022-10-16' 또는 end_date >= '2022-10-16' 둘 중 하나만 참이면 대여중으로 처리하고 있음. 그래서 출력해봤을 때 모두 다 '대여중'으로 나왔던 것!!!
그래서 AND로 연결해서 처리를 해야함! 


▶ DATE_FORMAT(날짜, '%Y-%m-%d) 대신 DATE(날짜컬럼)! 전자가 틀린 것은 아님 ;;

✅ 개선된 쿼리문

1. 자동차 ID 별로, 해당 날짜 포함이면 '대여중' 아니면 '대여 가능'  (불리언 집계)

>>> 💡 불린(True/False) 집계 : MYSQL에서만 가능
    : 불리언 표현식이 1 또는 0으로 평가되므로 MAX(...)로 True인지 확인이 가능함! 🔥🔥🔥🔥🔥

SELECT car_id,
       CASE WHEN MAX(DATE(start_date) <= '2022-10-16'
             AND '2022-10-16' <= DATE(end_date)) THEN '대여중'
            ELSE '대여 가능'
             END 'AVAILABILITY'
FROM car_rental_company_rental_history
GROUP BY car_id

2. 자동차 ID 내림차순 정렬

-- SELECT ...
-- FROM car_rental_company_rental_history
-- GROUP BY car_id
ORDER BY car_id DESC;

3. 최종 쿼리문

SELECT car_id,
       CASE WHEN MAX(DATE(start_date) <= '2022-10-16'
             AND '2022-10-16' <= DATE(end_date)) THEN '대여중'
            ELSE '대여 가능'
             END 'AVAILABILITY'
FROM car_rental_company_rental_history
GROUP BY car_id
ORDER BY car_id DESC;

🎯 또 다른 풀이

1) car_id 별로 해당 날짜 '2022-10-16'을 포함하는 행이 하나라도 있으면 SUM(...) > 0 으로 '대여중' !!

  • 즉, start <= date <= end 만족하는 행이 있으면 1 아니면 0
  • CASE WHEN SUM(case when start_date <= '날짜' AND end_date >= '날짜' then 1 else 0 end) > 0 THEN '대여중'
SELECT car_id,
       CASE                      <<< 이중 CASE WHEN 구문
         WHEN SUM(
           CASE 
             WHEN start_date <= '2022-10-16' 
              AND end_date   >= '2022-10-16' 
             THEN 1 ELSE 0 END
         ) > 0 THEN '대여중'
         ELSE '대여 가능'
       END AS AVAILABILITY
FROM car_rental_company_rental_history
GROUP BY car_id
ORDER BY car_id DESC;

끝.