728x90
문제
https://school.programmers.co.kr/learn/courses/30/lessons/151141
- 자동차 종류가 '트럭'인 자동차의 대여 기록에 대해서
- 대여 기록 별로 대여 금액(컬럼명: FEE) 구하고
- 대여 기록 ID와 대여 금액 리스트를 출력하는 SQL문 작성하기
- 대여 금액을 기준 내림차순, 대여 금액이 같은 경우 대여 기록 ID 기준 내림차순 정렬
테이블
CAR_RENTAL_COMPANY_CAR | |
CAR_RENTAL_COMPANY_RENTAL_HISTORY | |
CAR_RENTAL_COMPANY_DISCOUNT_PLAN |
풀이과정
- 테이블 조인할 때, 어떤 테이블을 중심으로 어떤 조인을 해야 원하는 결과를 얻을 수 있는지 생각하기
- CC 테이블과 RH 테이블 → INNER JOIN 하되, CAR_TYPE이 '트럭'일 때만 조인
- DP 테이블 → LEFT JOIN으로 CAR_TYPE이 '트럭'인 경우에만 조인 (CAR_TYPE이 '트럭'이 아닌 경우에는 모두 NULL 처리 됨)
- CASE WHEN 문을 사용해 각 대여 기간마다의 할인율 구해주기
- 이 때 주의할 점!
해당 조건문을 ON절에 적어줄 때랑 WHERE 조건절에 따로 빼서 적어줄 때의 결과값이 다름!
▶ LEFT JOIN의 ON절 사용
- 각 대여 기간마다의 할인율을 구하기 위해 CASE WHEN 문을 사용하고 있는데
'7일 미만' 조건에 대해서는 ELSE 부분에 NULL 처리를 하고 있음.
- 추후 SELECT문에서 따로 IFNULL 함수를 사용해 할인율을 0으로 만들어줘야 함
- NULL 처리된 모든 행까지도 빠짐없이 같이 출력되는 모습
1 2 3 4 5 6 7 8 9 10 | SELECT *, DATEDIFF(RH.END_DATE, RH.START_DATE)+1 DD FROM CAR_RENTAL_COMPANY_CAR CC JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY RH ON CC.CAR_ID = RH.CAR_ID AND CC.CAR_TYPE = '트럭' LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN DP ON CC.CAR_TYPE = DP.CAR_TYPE AND (CASE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 BETWEEN 7 AND 29 AND DP.DURATION_TYPE = '7일 이상' THEN DP.DISCOUNT_RATE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 BETWEEN 30 AND 89 AND DP.DURATION_TYPE = '30일 이상' THEN DP.DISCOUNT_RATE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 >= 90 AND DP.DURATION_TYPE = '90일 이상' THEN DP.DISCOUNT_RATE ELSE '' END) | cs |
▶ WHERE절 사용
- 각 대여 기간마다의 할인율을 구하기 위해 CASE WHEN 문을 사용하고 있는데
'7일 미만' 조건에 대해서는 ELSE 부분에 NULL 처리를 하고 있음 - NULL 처리된 모든 행이 제외되고 출력되는 모습
1 2 3 4 5 6 7 8 9 10 | SELECT *, DATEDIFF(RH.END_DATE, RH.START_DATE)+1 DD FROM CAR_RENTAL_COMPANY_CAR CC JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY RH ON CC.CAR_ID = RH.CAR_ID AND CC.CAR_TYPE = '트럭' LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN DP ON CC.CAR_TYPE = DP.CAR_TYPE WHERE (CASE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 BETWEEN 7 AND 29 AND DP.DURATION_TYPE = '7일 이상' THEN DP.DISCOUNT_RATE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 BETWEEN 30 AND 89 AND DP.DURATION_TYPE = '30일 이상' THEN DP.DISCOUNT_RATE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 >= 90 AND DP.DURATION_TYPE = '90일 이상' THEN DP.DISCOUNT_RATE ELSE '' END) | cs |
# 정답
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | SELECT DISTINCT RH.HISTORY_ID, ROUND(CC.DAILY_FEE * (1 - IFNULL(DP.DISCOUNT_RATE,0) * 0.01) * (DATEDIFF(RH.END_DATE, RH.START_DATE)+1),0) FEE FROM CAR_RENTAL_COMPANY_CAR CC JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY RH ON CC.CAR_ID = RH.CAR_ID AND CC.CAR_TYPE = '트럭' LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN DP ON CC.CAR_TYPE = DP.CAR_TYPE AND (CASE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 BETWEEN 7 AND 29 AND DP.DURATION_TYPE = '7일 이상' THEN DP.DISCOUNT_RATE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 BETWEEN 30 AND 89 AND DP.DURATION_TYPE = '30일 이상' THEN DP.DISCOUNT_RATE WHEN DATEDIFF(RH.END_DATE, RH.START_DATE)+1 >= 90 AND DP.DURATION_TYPE = '90일 이상' THEN DP.DISCOUNT_RATE END) ORDER BY FEE DESC, RH.HISTORY_ID DESC | cs |
728x90
'코딩테스트 > SQL 코드카타' 카테고리의 다른 글
MySQL 프로그래머스 | 상품을 구매한 회원 비율 구하기 (2) | 2024.09.19 |
---|---|
MySQL 프로그래머스 | 그룹별 조건에 맞는 식당 목록 출력하기 (1) | 2024.09.18 |
MySQL 프로그래머스 | 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기 (0) | 2024.09.16 |
MySQL 프로그래머스 | 자동차 평균 대여 기간 구하기 (DATEDIFF 함수 주의할 점, +1을 해줘야 하는 이유) (1) | 2024.09.13 |
MySQL 프로그래머스 | 조건에 맞는 개발자 (비트 연산자 활용) (1) | 2024.09.12 |
댓글