문제 : 자동차 대여 기록별 대여 금액 구하기
https://school.programmers.co.kr/learn/courses/30/lessons/151141?language=oracle
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
WITH TRUCK AS (
SELECT
H.HISTORY_ID,
H.CAR_ID,
I.CAR_TYPE,
I.DAILY_FEE,
H.START_DATE,
H.END_DATE,
H.END_DATE - H.START_DATE + 1 AS RENT_DAY,
(CASE
WHEN H.END_DATE - H.START_DATE + 1 >= 90 THEN '90일 이상'
WHEN H.END_DATE - H.START_DATE + 1 >= 30 THEN '30일 이상'
WHEN H.END_DATE - H.START_DATE + 1 >= 7 THEN '7일 이상'
ELSE '비대상'
END) AS DURATION_TYPE
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H
JOIN CAR_RENTAL_COMPANY_CAR I ON H.CAR_ID = I.CAR_ID
WHERE I.CAR_TYPE = '트럭'
)
SELECT
T.HISTORY_ID,
T.DAILY_FEE * COALESCE(1 - P.DISCOUNT_RATE/100, 1) * T.RENT_DAY AS FEE
FROM TRUCK T
LEFT JOIN
CAR_RENTAL_COMPANY_DISCOUNT_PLAN P
ON T.duration_type =P.duration_type
AND T.CAR_TYPE = P.CAR_TYPE
ORDER BY FEE DESC, T.HISTORY_ID DESC;
코드 해석
1. WITH 절 (TRUCK CTE)에서 기본 데이터 및 기간 정보 준비
WITH TRUCK AS (...) 부분에서는 최종 요금 계산에 필요한 모든 기초 데이터와 기간 정보를 준비
- 필터링
:CAR_RENTAL_COMPANY_CAR 테이블에서 CAR_TYPE이 '트럭'인 차량만 필터링 - 데이터 조인
: 필터링된 트럭 정보(I)와 렌탈 기록(H)을 CAR_ID로 연결 - 기간 계산 (RENT_DAY)
: H.END_DATE - H.START_DATE + 1를 사용하여 대여 시작일과 종료일을 모두 포함하는 정확한 대여 일수(RENT_DAY)를 계산 - 할인 기간 타입 분류 (DURATION_TYPE)
: 계산된 RENT_DAY를 기준으로 대여 기간을 '90일 이상', '30일 이상', '7일 이상', '비대상'의 네 가지 범주로 분류
2. 메인 쿼리에서 할인 플랜 조인 및 요금 계산
SELECT 문에서는 준비된 TRUCK 데이터를 할인 플랜과 연결하여 최종 요금을 산출
- LEFT JOIN
: TRUCK 테이블(T)에 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블(P)을 LEFT JOIN합니다. - JOIN 조건
: 조인 조건으로 T.DURATION_TYPE과 P.DURATION_TYPE, 그리고 T.CAR_TYPE과 P.CAR_TYPE이 모두 일치하는 레코드를 연결- 핵심: LEFT JOIN 덕분에 해당 DURATION_TYPE에 할인 플랜이 없더라도 (예: '비대상' 기간) 왼쪽의 대여 기록(TRUCK 데이터)은 유지됩니다.
- 최종 요금 계산 (FEE): 다음 수식을 사용하여 요금을 계산합니다.
- 할인 계수 처리: COALESCE(1 - P.DISCOUNT_RATE / 100, 1)을 사용
- 할인 플랜이 있는 경우: (예: 9)를 으로 나눈 후 에서 빼서 할인 적용 계수 (예: )를 사용
- 할인 플랜이 없는 경우: P.DISCOUNT_RATE가 NULL이 되므로, COALESCE 함수는 1을 반환하여 할인을 적용하지 않음
- 할인 계수 처리: COALESCE(1 - P.DISCOUNT_RATE / 100, 1)을 사용
코드는 좀 길지만 하나씩 풀어가면 풀 수 있는 문제였습니다
예전에 MySQL로 풀었던 걸 보니까 되게 복잡하고,우회적인 방법을 사용했더라구요 ㅎㅎ
지금은 복잡한 문제를 구조화하고 논리적으로 단순화하는 핵심 능력이 성장된 것 같습니다.
'코딩 테스트 > 02. SQL' 카테고리의 다른 글
| [solvesql_Lv2] 다음날 서울숲의 미세먼지 농도 나쁨 (0) | 2025.10.11 |
|---|---|
| [solvesql]MySQL_1 (Lv_2) (0) | 2025.10.11 |
| [프로그래머스]Oracle SQL_6(Lv4)/UNION ALL과 CONNECT BY (0) | 2025.10.03 |
| [프로그래머스]Oracle SQL_5(Lv4) (0) | 2025.10.02 |
| [프로그래머스]Oracle SQL_4(Lv4) (0) | 2025.10.02 |