어려운 JOIN 연습
https://school.programmers.co.kr/learn/courses/30/parts/17046
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
1. 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기
SELECT DISTINCT C.CAR_ID, C.CAR_TYPE, FLOOR(30*DAILY_FEE*(1 - DISCOUNT_RATE/100)) AS FEE
FROM CAR_RENTAL_COMPANY_CAR AS C
JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY AS H
ON C.CAR_ID = H.CAR_ID
JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN AS D
ON C.CAR_TYPE = D.CAR_TYPE AND
D.DURATION_TYPE = '30일 이상'
WHERE C.CAR_TYPE IN ('세단', 'SUV')
AND C.CAR_ID NOT IN (SELECT CAR_ID
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE NOT (END_DATE < '2022-11-01' OR
'2022-11-30' < START_DATE))
HAVING FEE BETWEEN 500000 AND 2000000-1
ORDER BY 3 DESC, 2, 1 DESC;
- 개인적으로 딱 깔끔하다고 느낀 풀이이다.
- ON 절에서 AND 또는 OR로 조건을 추가할 수 있다.
- MySQL에서 날짜 비교시에는 작은 따옴표 ' ' 로 묶어준다.
- 계산의 반복을 피하기 위해 되도록 SELECT 절에 계산 명시 후 HAVING 절에 해당 데이터를 이용하는 것도 좋을 것 같다.
2. 없어진 기록 찾기
-- 코드를 입력하세요
SELECT AO.ANIMAL_ID, AO.NAME
FROM ANIMAL_OUTS AO LEFT JOIN ANIMAL_INS AI ON AO.ANIMAL_ID=AI.ANIMAL_ID
WHERE AI.ANIMAL_ID IS NULL
ORDER BY 1, 2;
- LEFT JOIN 이 생각 났다! AO를 기준으로 LEFT JOIN을 할 때 AI에 존재하지 않는 데이터는 NULL로 처리해버릴 것이다.
3. 있었는데요 없었습니다.
-- 코드를 입력하세요
SELECT AO.ANIMAL_ID, AO.NAME
FROM ANIMAL_OUTS AO JOIN ANIMAL_INS AI ON AO.ANIMAL_ID=AI.ANIMAL_ID
WHERE AI.DATETIME > AO.DATETIME
ORDER BY AI.DATETIME;
4. 오랜 기간 보호한 동물
-- 코드를 입력하세요
SELECT AI.NAME, AI.DATETIME
FROM ANIMAL_INS AI LEFT JOIN ANIMAL_OUTS AO ON AO.ANIMAL_ID=AI.ANIMAL_ID
WHERE AO.ANIMAL_ID IS NULL
ORDER BY AI.DATETIME
LIMIT 3;
- DATETIME ASC -> 오래된 순, DESC -> 최신순
5. 보호소에서 중성화한 동물
SELECT AI.ANIMAL_ID, AI.ANIMAL_TYPE, AI.NAME
FROM ANIMAL_INS AI JOIN ANIMAL_OUTS AO ON AO.ANIMAL_ID=AI.ANIMAL_ID
WHERE AI.SEX_UPON_INTAKE LIKE "Intact%" and (AO.SEX_UPON_OUTCOME LIKE "Spayed%" OR AO.SEX_UPON_OUTCOME LIKE "Neutered%")
ORDER BY 1, 2, 3;
- 컬럼 도메인에 대해 좀 더 자세하게 설명해줬으면....
- LIKE ~ OR ~ 로 LIKE를 여러개 비교하는 것은 안된다.
6. 상품 별 오프라인 매출 구하기
-- 코드를 입력하세요
SELECT P.PRODUCT_CODE, SUM(OS.SALES_AMOUNT*P.PRICE) AS SALES
FROM PRODUCT P JOIN OFFLINE_SALE OS ON P.PRODUCT_ID=OS.PRODUCT_ID
GROUP BY OS.PRODUCT_ID
ORDER BY 2 DESC, 1;
7. 상품을 구매한 회원 비율 구하기
SELECT YEAR(O.SALES_DATE) AS YEAR, MONTH(O.SALES_DATE) AS MONTH,
COUNT( DISTINCT O.USER_ID) AS PURCHASED_USERS,
ROUND((COUNT(DISTINCT O.USER_ID)/(SELECT COUNT(*) FROM USER_INFO WHERE YEAR(JOINED) = 2021)),1) AS PURCHASED_RATIO
FROM ONLINE_SALE O
WHERE O.USER_ID IN (SELECT USER_ID FROM USER_INFO WHERE YEAR(JOINED) = 2021)
GROUP BY YEAR, MONTH
ORDER BY YEAR, MONTH;
- 서브쿼리를 활용한 문제. SELECT 절 안에서 서브 쿼리를 활용했다.
8. 5월 식품들의 총매출 조회하기
-- 코드를 입력하세요
SELECT FP.PRODUCT_ID, FP.PRODUCT_NAME, SUM(FP.PRICE*FO.AMOUNT) AS TOTAL_SALES
FROM FOOD_PRODUCT FP JOIN FOOD_ORDER FO ON FP.PRODUCT_ID=FO.PRODUCT_ID
WHERE FO.PRODUCE_DATE LIKE "2022-05%"
GROUP BY FO.PRODUCT_ID
ORDER BY 3 DESC, 1;
- FOOD_ORDER에 동일한 PRODUCT_ID를 가진 데이터가 있을 수 있음!
9. 주문량이 많은 아이스크림 조회하기
SELECT
F.FLAVOR
FROM
FIRST_HALF F INNER JOIN JULY J
ON F.FLAVOR = J.FLAVOR
GROUP BY
F.FLAVOR
ORDER BY
SUM(F.TOTAL_ORDER + J.TOTAL_ORDER) DESC
LIMIT 3;
- FLAVOR로 INNER JOIN하니 더 쉬움.
- 처음에는 J.TOTAL_ORDER에만 SUM을 적용했는데 값이 제대로 나오지 않음. TOTAL_ORDER의 총합으로 구해도 된다.
10. 조건에 맞는 도서와 저자 리스트 출력하기
-- 코드를 입력하세요
SELECT B.BOOK_ID, A.AUTHOR_NAME, DATE_FORMAT(B.PUBLISHED_DATE, "%Y-%m-%d") AS PUBLISHED_DATE
FROM BOOK B JOIN AUTHOR A ON B.AUTHOR_ID=A.AUTHOR_ID
WHERE B.CATEGORY="경제"
ORDER BY 3;
11. 그룹별 조건에 맞는 식당 목록 출력하기
-- 코드를 입력하세요
SELECT M.MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, "%Y-%m-%d") AS REVIEW_DATE
FROM MEMBER_PROFILE M JOIN REST_REVIEW R ON M.MEMBER_ID=R.MEMBER_ID
WHERE R.MEMBER_ID = (SELECT MEMBER_ID FROM REST_REVIEW GROUP BY MEMBER_ID
ORDER BY COUNT(*) DESC
LIMIT 1)
ORDER BY R.REVIEW_DATE, 2;
- 서브쿼리에서 정렬 시 GROUP BY한 값을 기준으로 COUNT(*) 정렬하는 것 주의!
12. FrontEnd 개발자 찾기
-- 코드를 작성해주세요
SELECT ID, EMAIL, FIRST_NAME, LAST_NAME
FROM DEVELOPERS
WHERE SKILL_CODE&(SELECT SUM(CODE) FROM SKILLCODES WHERE CATEGORY="Front End") > 0
ORDER BY 1;
회고
어느정도 JOIN에 익숙해졌다!
가끔 헷갈리는 것만 제외하면 4까지는 풀 수 있을 것 같다. 5는...문제를 많이 못봐서 모르겠음
갑자기 궁금해져서 찾아본 제약 조건 확인 명령어
SHOW CREATE TABLE your_table_name;

'코딩테스트' 카테고리의 다른 글
[MySQL] 프로그래머스 SQL 고득점 Kit - String, Date (1) | 2025.02.23 |
---|---|
[MySQL] 프로그래머스 SQL 고득점 Kit - IS NULL (0) | 2025.02.21 |
[MySQL] 프로그래머스 SQL 고득점 Kit - GROUP BY (1) | 2025.02.21 |
[MySQL] 프로그래머스 SQL 고득점 Kit - SUM, MAX, MIN (0) | 2025.02.21 |
[MySQL] 프로그래머스 SQL 고득점 Kit - SELECT (0) | 2025.02.20 |