[Programmers] 자동차 대여 기록 별 대여 금액 구하기

HAHAHELLO·2025년 7월 9일

SQL

목록 보기
17/17

Lv.4 자동차 대여 기록 별 대여 금액 구하기

문제

CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 자동차 종류가 '트럭'인 자동차의 대여 기록에 대해서 대여 기록 별로 대여 금액(컬럼명: FEE)을 구하여 대여 기록 ID와 대여 금액 리스트를 출력하는 SQL문을 작성해주세요. 결과는 대여 금액을 기준으로 내림차순 정렬하고, 대여 금액이 같은 경우 대여 기록 ID를 기준으로 내림차순 정렬해주세요.

예시


나의 풀이

WITH TB1 AS (
SELECT
	H.HISTORY_ID,
    H.CAR_ID,
	CASE
	 	WHEN DATEDIFF(H.END_DATE, H.START_DATE) + 1 >= 90 THEN '90일 이상'
     	WHEN DATEDIFF(H.END_DATE, H.START_DATE) + 1 >= 30 THEN '30일 이상'
     	WHEN DATEDIFF(H.END_DATE, H.START_DATE) + 1 >= 7 THEN '7일 이상'
     	ELSE '할인 없음'
    END AS RENT_PERIOD,
    DATEDIFF(H.END_DATE, H.START_DATE) + 1 AS COUNT_DATE,
 	C.DAILY_FEE,
 	C.CAR_TYPE
FROM
	CAR_RENTAL_COMPANY_RENTAL_HISTORY H
RIGHT JOIN CAR_RENTAL_COMPANY_CAR C ON C.CAR_ID = H.CAR_ID
WHERE
 	C.CAR_TYPE='트럭'
)

 
SELECT
	T.HISTORY_ID, 
    CASE
    	WHEN T.RENT_PERIOD IN ('7일 이상', '30일 이상', '90일 이상') THEN ROUND(((100 - P.DISCOUNT_RATE)/100) * T.DAILY_FEE * T.COUNT_DATE ,0)
     	ELSE T.DAILY_FEE * T.COUNT_DATE
     END AS FEE
FROM
	TB1 T
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN P 
	ON T.RENT_PERIOD = P.DURATION_TYPE
    AND T.CAR_TYPE = P.CAR_TYPE
ORDER BY
	FEE DESC, HISTORY_ID DESC;

끄적끄적

CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블의 DISCOUNT_RATE가 5% (정수 + 문자열) 형식으로 되어 있는데 이 형식으로도 연산이 되서 따로 형변환을 하지 않았다.
하지만 보통은 CAST를 사용해서 형변환을 해줘야 한다.

CAST

데이터 타입 일관성을 확보하고 연산 오류 방지를 위해 사용한다.
CAST(expression AS type)의 형태로 변환할 값(expression)과 변환할 데이터 타입(type)을 지정해주면 된다.

  • UNSIGNED: 정수
  • DECIMAL: 소수
  • DATE: 날짜
  • CHAR: 문자열

주의할점은 변환할 값이 타입과 맞이 않으면 NULL 반환 또는 에러가 발생한다는 점이다.

DECIMAL

DECIMAL

DECIMAL은 금융, 회계, 통계 등 정밀도가 필요한 계산에 사용하는 형식으로 소수점 이하 자릿수를 정확하게 표현할 수 있다.

DECIMAL(M,D) 형태로 사용되면 M은 전체 자릿수를, D는 소수점 이하 자릿수를 나타낸다. 정수부는 M-D 자리까지 가능하다.

DECIMAL(5,2) # 최대 999.99
DECIMAL(7,3) # chleo 9999.999

FLOAT/DOUBLE 과의 차이

FLOAT/DOUBLE은 주로 과학 계산, 기계 학습, 좌표 계산 등에 쓰인다.
DECIMALdl FLOAT/DOUBLE보다 속도는 느릴 수 있지만 정밀도는 보장된다.

참고로 FLOAT은 4바이트(32bit) 부동소수점 수이고 DOUBLE은 8바이트(64bit) 부동소수점 수이다.

profile
데이터 엔지니어가 되어 봅시다 🌈

0개의 댓글