
📑 1. 문제설명







🚀 2. 실패한 시도
❌ 첫번째 시도(실패)
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, j.daily_fee * ((100 - j.discount_rate)*0.01) * 30 AS fee
FROM (car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01'
ORDER BY fee DESC, j.car_type, j.car_id DESC

서브쿼리에서 SELECT절 안씀 -> 그래서 SELECT *써서 제출
❌두번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, j.daily_fee * ((100 - j.discount_rate)*0.01) * 30 AS fee
FROM (SELECT * from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01'
ORDER BY fee DESC, j.car_type, j.car_id DESC

서브쿼리에 중복 컬럼 있어서 필요한 컬럼만 다시 썼다.
❌ 세번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, j.daily_fee * ((100 - j.discount_rate)*0.01) * 30 AS fee
FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01'
ORDER BY fee DESC, j.car_type, j.car_id DESC

코드는 돌아가는데 실행결과가 딱봐도 정수가 아니라 실수로 출력됨...
계산식이 잘못된 것.. ROUND 함수 써서 정수부분만 남김
그리고 car_id 가 중복된게 많이 나와서 group by 절에서 묶어서 정리했다.
❌ 네 번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee
FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01'
group by car_id
ORDER BY fee DESC, j.car_type, j.car_id DESC

틀렸지만 거의 다 왔다...
WHERE절 논리 오류
WHERE car_type = '세단' OR 'SUV'
여기서 틀렸다. 'SUV'는 항상 TRUE
모든 car_type이 포함되는 오류
WHERE car_type IN ('세단', 'SUV')
❌ 다섯 번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee
FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type IN ('세단', 'SUV') AND h.end_date < '2024-11-01'
group by car_id
ORDER BY fee DESC, j.car_type, j.car_id DESC
여기서부터는 슬슬 쿼리도 길어지고 힘듦..
2시 넘어서 잠도 오고 어떻게 해야될지 모르겠다.
그리고 대소문자 구별도 안되고 줄도 안맞지만 나중에 정리하면 되니까....
나는 그냥 대여기간이 11월 1일 전에 종료된 거만 잡으면 될 줄알았는데
생각해보니 시작일도 11월 이전이면 안되는구나....
전체 데이터 중에 11월 1일부터 11월 30일까지 대여중인 차를 다 제외해야 함
하지만 문제에서 필요한 건? 2022년 11월 1일부터 11월 30일까지 ‘대여 가능한’ 차량
11월 전체 동안 이미 대여 중인 차
h.start_date <= '2022-11-01' AND h.end_date >= '2022-11-30'
h.start_date <= '2022-11-01'
대여가 11월 1일보다 "이전에 시작"되었거나 같은 날 시작
h.end_date >= '2022-11-30'
대여가 11월 30일보다 "이후에 끝나거나" 같은 날에 끝남
즉, 위 조건을 만족하는 차량은제외해야 하는 대상
다시 서브쿼리 씀...
❌ 여섯 번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee
FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type IN ('세단', 'SUV') AND
h.start_date <= '2022-11-01' AND h.end_date >= '2022-11-30'
group by car_id
ORDER BY fee DESC, j.car_type, j.car_id DESC
- 대여기간 종류를 간과함...
서브쿼리에서 JOIN 조건에 ON c.car_type = d.car_type AND d.duration_type = '30일 이상'
❌ 일곱 번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee
FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type IN ('세단', 'SUV') AND
(SELECT car_id FROM car_rental_company_rental_history
WHERE start_date <= '2022-11-01' AND end_date >= '2022-11-30')
group by car_id
ORDER BY fee DESC, j.car_type, j.car_id DESC

아하... WHERE절 서브쿼리를 = 없이 그냥 (SELECT car_id)로 썼기 때문에,
단일 값이 필요한 자리에 여러 행을 반환해서 오류가 발생한 것
일단 NOT EXISTS 로 수정해서 풀어보려고 함...
해당 기간 날짜에 대여중인 차 목록에 존재하지 않는 데이터만 걸러내는 것
❌ 여덟번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee
FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type IN ('세단', 'SUV') AND NOT EXISTS
(SELECT car_id FROM car_rental_company_rental_history
WHERE start_date <= '2022-11-01' AND end_date >= '2022-11-30')
group by car_id
ORDER BY fee DESC, j.car_type, j.car_id DESC
아... 이게 아니네
서브쿼리를 전체 차량에 공통으로 적용함
즉, 특정 차량(j.car_id)과 관계없이 전체 대여 기록에서 하나라도 11월에 겹치는 게 있으면 아무 차량도 통과 못한다...
h.car_id = j.car_id 를 넣어줘야 각 차량에 대해 11월과 겹치는 대여 기록이 없는지 검사한다...
❌ 아홉번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee
FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type IN ('세단', 'SUV')
AND NOT EXISTS (
SELECT 1
FROM car_rental_company_rental_history h2
WHERE h2.car_id = j.car_id
AND NOT (
h2.end_date < '2022-11-01' OR h2.start_date > '2022-11-30')
)
group by car_id
ORDER BY fee DESC, j.car_type, j.car_id DESC

계속 안되네 두시 반이 넘었는데
내가 이래서 맨날 못자고 4시간 자고 출근인거야...
문제에서 30일간의 대여 금액이 50만원 이상 200만원 미만인 자동차
ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) BETWEEN 500000 AND 2000000
조건 추가
아 너무 힘들다.... 오늘도 3시에 자게 생겼네
안돼도 끝내고 자야 한다
못끝내면 남의 답 봐서라도 마무리하고 자야 한다
머리 쓰기 싫어도 하던거 이어서 하고 결론을 내고 자야 햠....
안그러면 내일 하기 싫어짐..
⭕ 열번째 시도
-- 코드를 입력하세요
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee
FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j
INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
WHERE car_type IN ('세단', 'SUV')
AND NOT EXISTS (
SELECT car_id
FROM car_rental_company_rental_history h2
WHERE h2.car_id = j.car_id
AND NOT (
h2.end_date < '2022-11-01' OR h2.start_date > '2022-11-30')
)
AND ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) BETWEEN 500000 AND 2000000
group by car_id
ORDER BY fee DESC, j.car_type, j.car_id DESC

드디어.... 제출하고 깃에 백준허브로 커밋
상태가 group by 만 소문자로 되어 있네 정렬도 안맞지만 푼것에 대해 만족하고
아쉬운 점은 이거 백준허브는 한 번 커밋하면 문제 풀 때 재커밋이 안된다...;
⭐ 3. 정답코드
제출한 코드
SELECT
j.car_id,
j.car_type,
ROUND(j.daily_fee * ((100 - j.discount_rate) * 0.01) * 30) AS fee
FROM (
SELECT
c.car_id,
c.car_type,
c.daily_fee,
d.discount_rate
FROM car_rental_company_car c
INNER JOIN car_rental_company_discount_plan d
ON c.car_type = d.car_type
AND d.duration_type = '30일 이상'
) AS j
INNER JOIN car_rental_company_rental_history h
ON j.car_id = h.car_id
WHERE
j.car_type IN ('세단', 'SUV')
AND NOT EXISTS (
SELECT 1
FROM car_rental_company_rental_history h2
WHERE h2.car_id = j.car_id
AND NOT (
h2.end_date < '2022-11-01'
OR h2.start_date > '2022-11-30'
)
)
AND ROUND(j.daily_fee * ((100 - j.discount_rate) * 0.01) * 30)
BETWEEN 500000 AND 2000000
GROUP BY
j.car_id
ORDER BY
fee DESC,
j.car
보기좋게 정리했다.
여기서 한 가지 문제점이 있는데 내 코드에서 INNER JOIN rental_history도 생략 가능하다.
이 부분은 중복으로 불필요한 부분이다.
왜냐하면 NOT EXISTS로 대여 기록을 이미 체크하고 있기 때문이다.
기존 쿼리를 고쳐서 쓰다 보니 이렇게 되었다.
AS j
INNER JOIN car_rental_company_rental_history h
ON j.car_id = h.car_id
무의미하게 중복된 `rental_history h` 이 제거된다.
개선된 코드
SELECT
j.car_id,
j.car_type,
ROUND(j.daily_fee * ((100 - j.discount_rate) * 0.01) * 30) AS fee
FROM (
SELECT
c.car_id,
c.car_type,
c.daily_fee,
d.discount_rate
FROM car_rental_company_car c
INNER JOIN car_rental_company_discount_plan d
ON c.car_type = d.car_type
AND d.duration_type = '30일 이상'
) AS j
WHERE
j.car_type IN ('세단', 'SUV')
AND NOT EXISTS (
SELECT 1
FROM car_rental_company_rental_history h2
WHERE h2.car_id = j.car_id
AND NOT (
h2.end_date < '2022-11-01'
OR h2.start_date > '2022-11-30'
)
)
AND ROUND(j.daily_fee * ((100 - j.discount_rate) * 0.01) * 30)
BETWEEN 500000 AND 2000000
ORDER BY
fee DESC,
j.car_type ASC,
j.car_id DESC;
남이 푼 코드
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_discount_plan d
ON c.car_type = d.car_type AND d.duration_type = '30일 이상'
WHERE
c.car_type IN ('세단', 'SUV')
AND c.car_id IN (
SELECT car_id
FROM car_rental_company_rental_history
WHERE
start_date <= '2022-11-01'
AND end_date >= '2022-11-30'
GROUP BY car_id
)
AND ROUND(c.daily_fee * (1 - (d.discount_rate / 100)) * 30) BETWEEN 500000 AND 2000000
ORDER BY
fee DESC,
c.car_type ASC,
c.car_id DESC;
다른 코드 찾아보니까
1) 백분율 계산식...
`ROUND(c.daily_fee * (1 - (d.discount_rate / 100)) * 30)` 이렇게 하는게 더 깔끔하구나...
`ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30)` 이건 내꺼
2) group by 를 서브쿼리 안에 썼네 오케이...
GROUP BY는 서브쿼리 안에 두는 게 좋을까? 아니면 바깥 메인 쿼리에 두는 게 더 낫나?
바깥이 낫다고 한다....
3) 내일은 LEFT JOIN 버전으로 해보기
📌 TMI
내가 보려고 쓰는거
서브쿼리 안에서 GROUP BY + HAVING이 필요한 경우
비교 대상이 그룹 단위로 필터링되어야 할 때 서브쿼리에서 자주 쓰는 패턴
-- 3건 이상 예약된 차량만 필터링
SELECT car_id
FROM (
SELECT car_id
FROM car_rental_company_rental_history
GROUP BY car_id
HAVING COUNT(*) >= 3
) AS frequent
원하는 조건을 만족하는 키 집합만 외부 쿼리에서 사용할 수 있다.
예를 들어 대여 이력이 1건만 있는 차량을 찾고 싶다면
SELECT car_id
FROM car_rental_company_rental_history
GROUP BY car_id
HAVING COUNT(*) = 1
car_id별로 묶고, 1건만 있는 그룹만 반환하면 정확히 의도된 그룹 필터링이 가능하다
하지만 이 문제에서는 HAVING COUNT(*)가 필요 없음...
내일 다시 정리해야 겠다...
벌써 3시
오늘도 4시간 자고 출근각...
'코딩테스트 > SQL테스트' 카테고리의 다른 글
[프로그래머스] (MySQL) 오랜 기간 보호한 동물(1) (2) | 2025.05.19 |
---|---|
[프로그래머스] (MySQL) 있었는데요 없었습니다 (0) | 2025.05.18 |
[프로그래머스] (MySQL) 없어진 기록 찾기 (1) | 2025.05.18 |
[프로그래머스] (MySQL) 상품 별 오프라인 매출 구하기 (2) | 2025.05.18 |
[프로그래머스] (MySQL) 취소되지 않은 진료 예약 조회하기 (9) | 2025.01.22 |

📑 1. 문제설명







🚀 2. 실패한 시도
❌ 첫번째 시도(실패)
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, j.daily_fee * ((100 - j.discount_rate)*0.01) * 30 AS fee FROM (car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01' ORDER BY fee DESC, j.car_type, j.car_id DESC

서브쿼리에서 SELECT절 안씀 -> 그래서 SELECT *써서 제출
❌두번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, j.daily_fee * ((100 - j.discount_rate)*0.01) * 30 AS fee FROM (SELECT * from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01' ORDER BY fee DESC, j.car_type, j.car_id DESC

서브쿼리에 중복 컬럼 있어서 필요한 컬럼만 다시 썼다.
❌ 세번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, j.daily_fee * ((100 - j.discount_rate)*0.01) * 30 AS fee FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01' ORDER BY fee DESC, j.car_type, j.car_id DESC

코드는 돌아가는데 실행결과가 딱봐도 정수가 아니라 실수로 출력됨...
계산식이 잘못된 것.. ROUND 함수 써서 정수부분만 남김
그리고 car_id 가 중복된게 많이 나와서 group by 절에서 묶어서 정리했다.
❌ 네 번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type = '세단' OR 'SUV' AND h.end_date < '2024-11-01' group by car_id ORDER BY fee DESC, j.car_type, j.car_id DESC

틀렸지만 거의 다 왔다...
WHERE절 논리 오류
WHERE car_type = '세단' OR 'SUV'
여기서 틀렸다. 'SUV'는 항상 TRUE
모든 car_type이 포함되는 오류
WHERE car_type IN ('세단', 'SUV')
❌ 다섯 번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type) AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type IN ('세단', 'SUV') AND h.end_date < '2024-11-01' group by car_id ORDER BY fee DESC, j.car_type, j.car_id DESC
여기서부터는 슬슬 쿼리도 길어지고 힘듦..
2시 넘어서 잠도 오고 어떻게 해야될지 모르겠다.
그리고 대소문자 구별도 안되고 줄도 안맞지만 나중에 정리하면 되니까....
나는 그냥 대여기간이 11월 1일 전에 종료된 거만 잡으면 될 줄알았는데
생각해보니 시작일도 11월 이전이면 안되는구나....
전체 데이터 중에 11월 1일부터 11월 30일까지 대여중인 차를 다 제외해야 함
하지만 문제에서 필요한 건? 2022년 11월 1일부터 11월 30일까지 ‘대여 가능한’ 차량
11월 전체 동안 이미 대여 중인 차
h.start_date <= '2022-11-01' AND h.end_date >= '2022-11-30'
h.start_date <= '2022-11-01'
대여가 11월 1일보다 "이전에 시작"되었거나 같은 날 시작
h.end_date >= '2022-11-30'
대여가 11월 30일보다 "이후에 끝나거나" 같은 날에 끝남
즉, 위 조건을 만족하는 차량은제외해야 하는 대상
다시 서브쿼리 씀...
❌ 여섯 번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type IN ('세단', 'SUV') AND h.start_date <= '2022-11-01' AND h.end_date >= '2022-11-30' group by car_id ORDER BY fee DESC, j.car_type, j.car_id DESC
- 대여기간 종류를 간과함...
서브쿼리에서 JOIN 조건에 ON c.car_type = d.car_type AND d.duration_type = '30일 이상'
❌ 일곱 번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type IN ('세단', 'SUV') AND (SELECT car_id FROM car_rental_company_rental_history WHERE start_date <= '2022-11-01' AND end_date >= '2022-11-30') group by car_id ORDER BY fee DESC, j.car_type, j.car_id DESC

아하... WHERE절 서브쿼리를 = 없이 그냥 (SELECT car_id)로 썼기 때문에,
단일 값이 필요한 자리에 여러 행을 반환해서 오류가 발생한 것
일단 NOT EXISTS 로 수정해서 풀어보려고 함...
해당 기간 날짜에 대여중인 차 목록에 존재하지 않는 데이터만 걸러내는 것
❌ 여덟번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type IN ('세단', 'SUV') AND NOT EXISTS (SELECT car_id FROM car_rental_company_rental_history WHERE start_date <= '2022-11-01' AND end_date >= '2022-11-30') group by car_id ORDER BY fee DESC, j.car_type, j.car_id DESC
아... 이게 아니네
서브쿼리를 전체 차량에 공통으로 적용함
즉, 특정 차량(j.car_id)과 관계없이 전체 대여 기록에서 하나라도 11월에 겹치는 게 있으면 아무 차량도 통과 못한다...
h.car_id = j.car_id 를 넣어줘야 각 차량에 대해 11월과 겹치는 대여 기록이 없는지 검사한다...
❌ 아홉번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type IN ('세단', 'SUV') AND NOT EXISTS ( SELECT 1 FROM car_rental_company_rental_history h2 WHERE h2.car_id = j.car_id AND NOT ( h2.end_date < '2022-11-01' OR h2.start_date > '2022-11-30') ) group by car_id ORDER BY fee DESC, j.car_type, j.car_id DESC

계속 안되네 두시 반이 넘었는데
내가 이래서 맨날 못자고 4시간 자고 출근인거야...
문제에서 30일간의 대여 금액이 50만원 이상 200만원 미만인 자동차
ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) BETWEEN 500000 AND 2000000
조건 추가
아 너무 힘들다.... 오늘도 3시에 자게 생겼네
안돼도 끝내고 자야 한다
못끝내면 남의 답 봐서라도 마무리하고 자야 한다
머리 쓰기 싫어도 하던거 이어서 하고 결론을 내고 자야 햠....
안그러면 내일 하기 싫어짐..
⭕ 열번째 시도
-- 코드를 입력하세요 SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) AS fee FROM (SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate from car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상') AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE car_type IN ('세단', 'SUV') AND NOT EXISTS ( SELECT car_id FROM car_rental_company_rental_history h2 WHERE h2.car_id = j.car_id AND NOT ( h2.end_date < '2022-11-01' OR h2.start_date > '2022-11-30') ) AND ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30) BETWEEN 500000 AND 2000000 group by car_id ORDER BY fee DESC, j.car_type, j.car_id DESC

드디어.... 제출하고 깃에 백준허브로 커밋
상태가 group by 만 소문자로 되어 있네 정렬도 안맞지만 푼것에 대해 만족하고
아쉬운 점은 이거 백준허브는 한 번 커밋하면 문제 풀 때 재커밋이 안된다...;
⭐ 3. 정답코드
제출한 코드
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate) * 0.01) * 30) AS fee FROM ( SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate FROM car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상' ) AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id WHERE j.car_type IN ('세단', 'SUV') AND NOT EXISTS ( SELECT 1 FROM car_rental_company_rental_history h2 WHERE h2.car_id = j.car_id AND NOT ( h2.end_date < '2022-11-01' OR h2.start_date > '2022-11-30' ) ) AND ROUND(j.daily_fee * ((100 - j.discount_rate) * 0.01) * 30) BETWEEN 500000 AND 2000000 GROUP BY j.car_id ORDER BY fee DESC, j.car
보기좋게 정리했다.
여기서 한 가지 문제점이 있는데 내 코드에서 INNER JOIN rental_history도 생략 가능하다.
이 부분은 중복으로 불필요한 부분이다.
왜냐하면 NOT EXISTS로 대여 기록을 이미 체크하고 있기 때문이다.
기존 쿼리를 고쳐서 쓰다 보니 이렇게 되었다.
AS j INNER JOIN car_rental_company_rental_history h ON j.car_id = h.car_id
무의미하게 중복된 `rental_history h` 이 제거된다.
개선된 코드
SELECT j.car_id, j.car_type, ROUND(j.daily_fee * ((100 - j.discount_rate) * 0.01) * 30) AS fee FROM ( SELECT c.car_id, c.car_type, c.daily_fee, d.discount_rate FROM car_rental_company_car c INNER JOIN car_rental_company_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상' ) AS j WHERE j.car_type IN ('세단', 'SUV') AND NOT EXISTS ( SELECT 1 FROM car_rental_company_rental_history h2 WHERE h2.car_id = j.car_id AND NOT ( h2.end_date < '2022-11-01' OR h2.start_date > '2022-11-30' ) ) AND ROUND(j.daily_fee * ((100 - j.discount_rate) * 0.01) * 30) BETWEEN 500000 AND 2000000 ORDER BY fee DESC, j.car_type ASC, j.car_id DESC;
남이 푼 코드
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_discount_plan d ON c.car_type = d.car_type AND d.duration_type = '30일 이상' WHERE c.car_type IN ('세단', 'SUV') AND c.car_id IN ( SELECT car_id FROM car_rental_company_rental_history WHERE start_date <= '2022-11-01' AND end_date >= '2022-11-30' GROUP BY car_id ) AND ROUND(c.daily_fee * (1 - (d.discount_rate / 100)) * 30) BETWEEN 500000 AND 2000000 ORDER BY fee DESC, c.car_type ASC, c.car_id DESC;
다른 코드 찾아보니까
1) 백분율 계산식...
`ROUND(c.daily_fee * (1 - (d.discount_rate / 100)) * 30)` 이렇게 하는게 더 깔끔하구나...
`ROUND(j.daily_fee * ((100 - j.discount_rate)*0.01) * 30)` 이건 내꺼
2) group by 를 서브쿼리 안에 썼네 오케이...
GROUP BY는 서브쿼리 안에 두는 게 좋을까? 아니면 바깥 메인 쿼리에 두는 게 더 낫나?
바깥이 낫다고 한다....
3) 내일은 LEFT JOIN 버전으로 해보기
📌 TMI
내가 보려고 쓰는거
서브쿼리 안에서 GROUP BY + HAVING이 필요한 경우
비교 대상이 그룹 단위로 필터링되어야 할 때 서브쿼리에서 자주 쓰는 패턴
-- 3건 이상 예약된 차량만 필터링 SELECT car_id FROM ( SELECT car_id FROM car_rental_company_rental_history GROUP BY car_id HAVING COUNT(*) >= 3 ) AS frequent
원하는 조건을 만족하는 키 집합만 외부 쿼리에서 사용할 수 있다.
예를 들어 대여 이력이 1건만 있는 차량을 찾고 싶다면
SELECT car_id FROM car_rental_company_rental_history GROUP BY car_id HAVING COUNT(*) = 1
car_id별로 묶고, 1건만 있는 그룹만 반환하면 정확히 의도된 그룹 필터링이 가능하다
하지만 이 문제에서는 HAVING COUNT(*)가 필요 없음...
내일 다시 정리해야 겠다...
벌써 3시
오늘도 4시간 자고 출근각...
'코딩테스트 > SQL테스트' 카테고리의 다른 글
[프로그래머스] (MySQL) 오랜 기간 보호한 동물(1) (2) | 2025.05.19 |
---|---|
[프로그래머스] (MySQL) 있었는데요 없었습니다 (0) | 2025.05.18 |
[프로그래머스] (MySQL) 없어진 기록 찾기 (1) | 2025.05.18 |
[프로그래머스] (MySQL) 상품 별 오프라인 매출 구하기 (2) | 2025.05.18 |
[프로그래머스] (MySQL) 취소되지 않은 진료 예약 조회하기 (9) | 2025.01.22 |