문제부터 이해하기 쉽지 않아서 간만에 엄청 오래걸리고 엄청 고민한 문제였다.
같이 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의 특성 때문인지 쿼리의 양이 많아지고 복잡해질수록 가독성이 너무 끔찍해진다.
짜다가도, 짜고 나서도 한눈에 잘 들어오지 않아 일부 가볍게 포맷팅 진행했다.
진짜 간만에 매운 문제였다...
'프로그래머스 > 코딩테스트 연습' 카테고리의 다른 글
SQL lv4 언어별 개발자 분류하기 (0) | 2024.05.02 |
---|---|
SQL lv3 물고기 종류 별 대어 찾기 (0) | 2024.04.30 |
SQL lv3 카테고리 별 도서 판매량 집계하기 (0) | 2024.04.24 |
SQL lv4 식품분류별 가장 비싼 식품의 정보 조회하기 (0) | 2024.04.24 |
SQL lv2 상품 별 오프라인 매출 구하기 (0) | 2024.04.24 |