SQL/문제

SQL | 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기, 오프라인/온라인 판매 데이터 통합하기, 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기

jjangdoll 2025. 1. 5. 12:28

대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기

https://school.programmers.co.kr/learn/courses/30/lessons/151139

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


1. 내가 쓴 답 (서브쿼리)

-- 대여 시작일을 기준
-- 2022년 8월 ~ 2022년 10월까지 대여 횟수 5회 이상
-- 월 기준 오름차순, 자동차 아이디 기준 내림차순
-- 대여횟수 0이면 제외
SELECT
    MONTH(START_DATE) AS MONTH,
    CAR_ID,
    COUNT(*) AS RECORDS
FROM
    CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE CAR_ID IN (
            SELECT
                CAR_ID
            FROM
             CAR_RENTAL_COMPANY_RENTAL_HISTORY
	# 대여 시작일 조건검
            WHERE 
            	DATE(START_DATE) >= '2022-08-01' 
           	 	AND DATE(START_DATE) <= '2022-10-31'
            GROUP BY CAR_ID
            HAVING COUNT(*)>=5)
	# 서브쿼리에서는 차 아이디에 관해서만 조건 걸었으므로 메인 쿼리에서 다시 날짜 조건
AND DATE(START_DATE) >= '2022-08-01' 
AND DATE(START_DATE) <= '2022-10-31' 
GROUP BY MONTH(START_DATE), CAR_ID
ORDER BY MONTH, CAR_ID DESC ;

2. 임정튜터님 정답 참고 (with)

WITH a AS
    (SELECT
        CAR_ID
    FROM
        CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE 
         MONTH(START_DATE) IN (8, 9, 10)
    GROUP BY CAR_ID
    HAVING COUNT(*)>=5)
SELECT
    MONTH(START_DATE) AS MONTH,
    CAR_ID,
    COUNT(*) AS RECORDS
FROM
    CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE
    MONTH(START_DATE) IN (8, 9, 10)
    AND CAR_ID IN (SELECT CAR_ID FROM a)
GROUP BY MONTH(START_DATE), CAR_ID
ORDER BY MONTH, CAR_ID DESC ;

 

💡 MONTH(START_DATE) IN (8, 9, 10) 이렇게 하면 훨씬 간단
💡 with가 덜 헷갈려서 쓰려다가 못썼는데 이런 식으로 쓸 수 있구나 참고


오프라인/온라인 판매 데이터 통합하기

https://school.programmers.co.kr/learn/courses/30/lessons/131537

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


-- 2022년 3월 
-- 판매 날짜, 상품 아이디, 유저 아이디, 판매량
-- 오프라라인 판매 데이터 유저 아이디는 NULL로 표시
-- 판매일, 상품 아이디, 유저 아이디 기준 오름차순
SELECT
    LEFT(SALES_DATE,10) SALES_DATE,
    PRODUCT_ID,
    USER_ID,
    SALES_AMOUNT
FROM
(
    SELECT USER_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE
    FROM ONLINE_SALE
    WHERE LEFT(SALES_DATE,10) LIKE '2022-03%'
    UNION ALL   # UNION 으로 묶을 때 칼럼이 일치하지 않을 경우 NULL써서 해결 가능
    SELECT NULL, PRODUCT_ID, SALES_AMOUNT, SALES_DATE
    FROM OFFLINE_SALE
    WHERE LEFT(SALES_DATE,10) LIKE '2022-03%') a
ORDER BY SALES_DATE, PRODUCT_ID, USER_ID ;

💡UNION 으로 묶을 때 칼럼이 일치하지 않을 경우 NULL 써서 해결 가능


특정 기간동안 대여 가능한 자동차들의 대여비용 구하기

https://school.programmers.co.kr/learn/courses/30/lessons/157339

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


-- 세단, SUV 중
-- 2022-11-01 ~ 2022-11-30 대여가능 AND 50<= 대여 금액 <200
-- 자동차 아이디, 자동차 종류, 대여금액
-- 대여 금액 내림차순, 자동차 종류 오름차순, 자동차 아이디 내림차순
SELECT
    c.CAR_ID,
    c.CAR_TYPE,
    ROUND(c.DAILY_FEE * (1-d.DISCOUNT_RATE/100) * 30) AS FEE
FROM
    CAR_RENTAL_COMPANY_CAR c 
    JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY h ON c.CAR_ID = h.CAR_ID 
    JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN d ON c.CAR_TYPE = d.CAR_TYPE
WHERE   
    c.CAR_TYPE IN ('SUV','세단')
    AND d.DURATION_TYPE = '30일 이상'
GROUP BY c.CAR_ID
HAVING  FEE >= 500000 AND FEE < 2000000
        AND MAX(h.END_DATE) < '2022-11-01'
ORDER BY FEE DESC, c.CAR_TYPE, c.CAR_ID DESC ;

📍 처음에 쓴 답 

AND h.START_DATE NOT LIKE '2022-11%'
AND h.END_DATE NOT LIKE '2022-11%'

📍 정답

MAX(h.END_DATE) < '2022-11-01'

💡 내가 쓴 답은 개별적으로 11월이 아닌 모든 달을 조회 (ex.시작일 10월이고 종료일 12월인 기록도 조회되기 때문에 조건에 부합하지 않음)

💡 정답은 제일로 늦게 종료된 날짜가 11월 1일보다 작기 때문에 조건에 부합