[프로그래머스] MySQL / 자동차 대여 기록 별 대여 금액 구하기

2024. 1. 8. 16:23Coding/프로그래머스-SQL

문제 링크

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 

 

코드

WITH value AS (
    SELECT car.daily_fee, car.car_type, his.history_id,
           DATEDIFF(end_date, start_date) + 1 AS period,
    CASE 
      WHEN DATEDIFF(end_date, start_date) + 1 >= 90 THEN '90일 이상'
      WHEN DATEDIFF(end_date, start_date) + 1 >= 30 THEN '30일 이상'
      WHEN DATEDIFF(end_date, start_date) + 1 >= 7 THEN '7일 이상'
      ELSE 'NONE' END AS duration_type
FROM car_rental_company_rental_history AS his
INNER JOIN car_rental_company_car AS car ON car.car_id = his.car_id
WHERE car.car_type = '트럭')


SELECT value.history_id, 
    ROUND(value.daily_fee * value.period * 
          (100 - IFNULL(plan.discount_rate,0)) / 100) AS FEE
FROM value
LEFT JOIN car_rental_company_discount_plan AS plan 
    ON plan.duration_type = value.duration_type 
    AND plan.car_type = value.car_type
ORDER BY 2 DESC, 1 DESC

이 문제는 너무 어려워서 인터넷의 도움을(..) 받았는데 해설을 해보자면 다음과 같다. 

1. With 절은 우선 하나의 서브쿼리 또는 임시 테이블 기능을 해주는 절이다. With 절로 우선 임시 테이블을 하나 만들어서 문제에서 정한대로 90일 이상, 30일 이상, 7일 이상의 케이스를 CASE WHEN THEN 구문으로 분류해준다. 

2. FEE 칼럼은 정수 값을 나눠주어야 하므로 ROUND() 함수의 두번째 항에는 아무 숫자를 넣지 않아도 된다. 대신 null 값을 넣으면 null값이 출력되는 것은 막아야 하므로 IFNULL을 이용해 NULL 값이 0이 출력되도록 한다. 

3. 1에서 정의한 with절의 value 테이블을 두번째 SELECT 절에 끌어와서 사용한다. 

4. 대여 기록이 기준이 되고, 대여 금액 리스트는 그에 따른 결과 값 정도로 보면 될 거 같다. 따라서 LEFT JOIN을 with 테이블에 걸어준다.