본문 바로가기
프로그래머스/코딩테스트 연습

SQL lv4 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기

by 포잉띠 2024. 4. 29.

 

문제부터 이해하기 쉽지 않아서 간만에 엄청 오래걸리고 엄청 고민한 문제였다.

같이 SQL 스터디 하는 분의 도움을 받아서 겨우 해결했다.

 

정답코드는 아래와 같다.

WITH DIFF AS (
    SELECT 
        DISTINCT a.CAR_ID, h.END_DATE, h.START_DATE
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY h
    JOIN CAR_RENTAL_COMPANY_CAR a ON a.CAR_ID = h.CAR_ID 
    WHERE END_DATE >= '2022-11-01' AND START_DATE <= '2022-11-30'
),
ct AS (
    SELECT 
        CAR_TYPE, DISCOUNT_RATE
    FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN
    WHERE CAR_TYPE IN ("세단", "SUV")
    AND DURATION_TYPE = "30일 이상"
)
SELECT 
    c.CAR_ID, 
    c.CAR_TYPE, 
    truncate(30 * (c.DAILY_FEE - c.DAILY_FEE * (t.DISCOUNT_RATE * 0.01)),0) AS FEE
FROM CAR_RENTAL_COMPANY_CAR c
LEFT JOIN DIFF d ON c.CAR_ID = d.CAR_ID
JOIN ct t ON t.CAR_TYPE = c.CAR_TYPE
WHERE d.CAR_ID IS NULL
AND 30 * (c.DAILY_FEE - c.DAILY_FEE * t.DISCOUNT_RATE * 0.01) >= 500000 
AND 30 * (c.DAILY_FEE - c.DAILY_FEE * t.DISCOUNT_RATE * 0.01) < 2000000
GROUP BY c.CAR_ID
ORDER BY FEE DESC, c.CAR_TYPE ASC, c.CAR_ID DESC

처음에는 DIFF 테이블에 11월에 해당하지 않는애들만 모아서 해결하려 했으나, 날짜가 애매하게 겹치는 레코드들이 존재해서 실패했다.

여기서 스터디 같이 하는 분께 도움을 받았다.

11월에 빌릴 수 있는걸 조회하는게 아니라 11월에 빌려진것을 조회하고 not in으로 그 부분들을 제외하여 조회하는 방식으로 푸셨다.

다만 그분은 서브쿼리를 사용하셔서 푸셨지만 나는 서브쿼리에 사용이 미숙하고 이해하기가 힘들어서 with절 활용하여 

LEFT JOIN 으로 11월에 빌려진 애들 제외하고는 NULL로 들어오게 하여 is null로 11월에 빌릴 수 있는애들을 필터링 했다.

확실히 SQL의 특성 때문인지 쿼리의 양이 많아지고 복잡해질수록 가독성이 너무 끔찍해진다.

짜다가도, 짜고 나서도 한눈에 잘 들어오지 않아 일부 가볍게 포맷팅 진행했다.

진짜 간만에 매운 문제였다...