테이블 정보
문제
CAR_RENTAL_COMPANY_CAR 테이블과 CAR_RENTAL_COMPANY_RENTAL_HISTORY 테이블과 CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블에서 자동차 종류가 '트럭'인 자동차의 대여 기록에 대해서
대여 기록 별로 대여 금액(컬럼명: FEE)을 구하여 대여 기록 ID와 대여 금액 리스트를 출력하는 SQL문을 작성해주세요.
결과는 대여 금액을 기준으로 내림차순 정렬하고, 대여 금액이 같은 경우 대여 기록 ID를 기준으로 내림차순 정렬해주세요.
예시
주의 사항
FEE의 경우 예시처럼 정수부분만 출력되어야 합니다.
문제 풀이 1 (MySQL)
데이터 타입을 꼼꼼히 살펴보지 않으면 어떻게 되는지 느끼게 해준 문제이다.
아래 코드는 답은 맞았으나 문제 요구사항에 적합하지 않은 코드입니다ㅠㅠ
SET @SEVEN = -1, @THIRTY = -1, @NINETY = -1;
SELECT CAST(SUBSTRING_INDEX(DISCOUNT_RATE, '%', 1) AS UNSIGNED)
INTO @SEVEN
FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN
WHERE DURATION_TYPE = '7일 이상' AND CAR_TYPE = '트럭';
SELECT CAST(SUBSTRING_INDEX(DISCOUNT_RATE, '%', 1) AS UNSIGNED)
INTO @THIRTY
FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN
WHERE DURATION_TYPE = '30일 이상' AND CAR_TYPE = '트럭';
SELECT CAST(SUBSTRING_INDEX(DISCOUNT_RATE, '%', 1) AS UNSIGNED)
INTO @NINETY
FROM CAR_RENTAL_COMPANY_DISCOUNT_PLAN
WHERE DURATION_TYPE = '90일 이상' AND CAR_TYPE = '트럭';
WITH CAR_INFO AS (
SELECT
HISTORY_ID,
CRCC.CAR_ID,
DATEDIFF(END_DATE, START_DATE) + 1 AS RENTAL_PERIOD,
DAILY_FEE
FROM CAR_RENTAL_COMPANY_CAR AS CRCC
INNER JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY AS CRCRH
ON CRCC.CAR_ID = CRCRH.CAR_ID
WHERE CAR_TYPE = '트럭'
)
SELECT
HISTORY_ID,
CASE
WHEN RENTAL_PERIOD >= 90 THEN ROUND((100 - @NINETY) / 100 * RENTAL_PERIOD * DAILY_FEE)
WHEN RENTAL_PERIOD >= 30 THEN ROUND((100 - @THIRTY) / 100 * RENTAL_PERIOD * DAILY_FEE)
WHEN RENTAL_PERIOD >= 7 THEN ROUND((100 - @SEVEN) / 100 * RENTAL_PERIOD * DAILY_FEE)
WHEN RENTAL_PERIOD < 7 THEN ROUND(RENTAL_PERIOD * DAILY_FEE)
END AS FEE
FROM CAR_INFO
ORDER BY FEE DESC, HISTORY_ID DESC;
문제 상단에서
CAR_RENTAL_COMPANY_DISCOUNT_PLAN 테이블의 데이터 타입을 보면
DISCOUNT_RATE는 INTEGER로 되어있다.
그러나 나의 경우 문제가 길어지면 테이블을 빠르게 훑어보고
아래 예시를 보면서 문제 흐름을 파악하는 습관이 있는데,
아래 예시에는 DISCOUNT_RATE 컬럼 값에 '%'가 뒤에 붙어 있길래
데이터 타입이 VARCHAR(255)인 줄 알았다......
사실상 위에 있는 문제 풀이 1 코드는 나혼자서 똥꼬쇼하면서 작성한 코드이다.....ㅠ
시간에 쫓긴다고 빠르게 읽지 말고 주어진 조건들을 꼼꼼히 읽어야겠다...
문제 풀이 2 (MySQL)
문제를 풀고 나서 더 나은 방식을 찾기 위해 여러 답안들을 구경해 봤는데, 개인적으로 문제 풀이 1의 방식보다 문제 풀이 2의 방식이 훨씬 더 깔끔하고 좋은 것 같다.
WITH CAR_INFO AS (
SELECT
HISTORY_ID,
CRCC.CAR_ID,
CAR_TYPE,
DATEDIFF(END_DATE, START_DATE) + 1 AS RENTAL_PERIOD,
DAILY_FEE,
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 CRCRH
INNER JOIN CAR_RENTAL_COMPANY_CAR AS CRCC
ON CRCC.CAR_ID = CRCRH.CAR_ID
WHERE CRCC.CAR_TYPE = '트럭'
)
SELECT
HISTORY_ID,
ROUND(DAILY_FEE * RENTAL_PERIOD * (100 - IFNULL(CRCDP.DISCOUNT_RATE, 0)) / 100) AS FEE
FROM CAR_INFO
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN AS CRCDP
ON CRCDP.DURATION_TYPE = CAR_INFO.DURATION_TYPE AND CRCDP.CAR_TYPE = CAR_INFO.CAR_TYPE
ORDER BY FEE DESC, HISTORY_ID DESC;
문제를 꼼꼼히 읽고 데이터 타입들을 잘 살펴보자!!
참고
MySQL에서 특정 문자로 문자열 SPLIT 하기 - SUBSTRING_INDEX
MYSQL에서는 특정 문자를 기준으로 SPLIT해서 해당 값을 여러 열로 나누어야 할 일이 발생했을때 사용하는 방법을 작성해보겠습니다. 위와같이 THRESHOLD라는 컬럼이 파이프라인( | )으로 이루어져 있
dreamcoding.tistory.com
[개발] mysql 에서 문자를 숫자로 변환하는 방법 — Steemit
MySQL에서 문자를 숫자로 바꾸는 방법은 CAST나 CONVERT 함수를 사용하는 것입니다. 이 함수들은 문자열을 숫자로 변환할 수 있습니다. 예를 들어, CAST 함수를 사용하여 문자열을 정수로 변환하려면
steemit.com
velog
velog.io
'SQL 문제 풀이' 카테고리의 다른 글
[LeetCode Hard] 262. Trips and Users (0) | 2024.02.28 |
---|---|
[프로그래머스 Level 4] 우유와 요거트가 담긴 장바구니 (0) | 2024.01.25 |
[LeetCode Hard] 601. Human Traffic of Stadium (0) | 2024.01.16 |
[LeetCode Medium] 1341. Movie Rating (0) | 2024.01.12 |
[LeetCode Hard] 185. Department Top Three Salaries (2) | 2024.01.07 |