천천히 빛나는

MySQL : JOIN 연산 고득점 Kit 본문

STUDY/MYSQL

MySQL : JOIN 연산 고득점 Kit

까만콩 •ᴥ• 2023. 10. 21. 17:17

프로그래머스 SQL 고득점 Kit의 JOIN 문제입니다.

https://school.programmers.co.kr/learn/challenges?tab=sql_practice_kit

1. 주문량이 많은 아이스크림 조회하기

SELECT F.FLAVOR
FROM FIRST_HALF AS F, JULY AS J
WHERE F.FLAVOR = J.FLAVOR
GROUP BY F.FLAVOR
ORDER BY (SUM(J.TOTAL_ORDER) + F.TOTAL_ORDER) DESC
LIMIT 3;

INNER JOIN이기 때문에 WHERE 대신 JOIN JULY AS J ON F.FLAVOR = J.FLAVOR 해도 된다

 

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

SELECT DISTINCT C.CAR_ID, C.CAR_TYPE, ROUND(C.DAILY_FEE *((100-P.DISCOUNT_RATE)/100)* 30) AS FEE
FROM CAR_RENTAL_COMPANY_CAR AS C, CAR_RENTAL_COMPANY_RENTAL_HISTORY AS H, CAR_RENTAL_COMPANY_DISCOUNT_PLAN AS P
WHERE C.CAR_ID = H.CAR_ID AND C.CAR_TYPE = P.CAR_TYPE
AND P.DURATION_TYPE='30일 이상'
AND C.CAR_ID NOT IN (SELECT CAR_ID
                   FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
                   WHERE END_DATE > '2022-11-01' AND START_DATE <'2022-12-01')
AND ROUND(C.DAILY_FEE *((100-P.DISCOUNT_RATE)/100)* 30) BETWEEN 500000 AND 1999999
ORDER BY FEE DESC, C.CAR_TYPE, C.CAR_ID DESC

문제를 푸는데 꽤 많이 헤맸다.

NOT IN을 사용했다. 끝나는 날이 마지막 기간 밖에 있고 시작하는 날이 기간 내에 있는 차들은 제외가 된다.

https://coduking.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-SQL-%ED%8A%B9%EC%A0%95-%EA%B8%B0%EA%B0%84%EB%8F%99%EC%95%88-%EB%8C%80%EC%97%AC-%EA%B0%80%EB%8A%A5%ED%95%9C-%EC%9E%90%EB%8F%99%EC%B0%A8%EB%93%A4%EC%9D%98-%EB%8C%80%EC%97%AC%EB%B9%84%EC%9A%A9-%EA%B5%AC%ED%95%98%EA%B8%B0

 

[프로그래머스 SQL] 특정 기간동안 대여 가능한 자동차들의 대여비용 구하기

정답 쿼리 SELECT DISTINCT(C.CAR_ID), C.CAR_TYPE, ROUND(DAILY_FEE * 30 - (DAILY_FEE * 30 * (DISCOUNT_RATE/100))) 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 P

coduking.com

 

3. 조건에 맞는 도서와 저자 리스트 출력하기

SELECT BOOK_ID, AUTHOR_NAME, DATE_FORMAT(PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK
JOIN AUTHOR ON BOOK.AUTHOR_ID = AUTHOR.AUTHOR_ID
WHERE CATEGORY = '경제'
ORDER BY PUBLISHED_DATE

이번엔 WHERE 대신 JOIN을 사용해서 내부조인을 구현해주었다

 

4. 5월 식품들의 총매출 조회하기

SELECT P.PRODUCT_ID, P.PRODUCT_NAME, P.PRICE * SUM(O.AMOUNT) AS TOTAL_SALES
FROM FOOD_PRODUCT AS P
JOIN FOOD_ORDER AS O ON P.PRODUCT_ID = O.PRODUCT_ID
WHERE YEAR(PRODUCE_DATE) = 2022 AND MONTH(PRODUCE_DATE) = 5
GROUP BY  P.PRODUCT_ID
ORDER BY TOTAL_SALES DESC, P.PRODUCT_ID

어렵지 않은 INNER JOIN 문제였다

 

5. 그룹별 조건에 맞는 식당 목록 출력하기

SELECT P.MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
FROM MEMBER_PROFILE AS P
JOIN REST_REVIEW AS R ON P.MEMBER_ID = R.MEMBER_ID
WHERE P.MEMBER_ID = (SELECT MEMBER_ID
                    FROM REST_REVIEW
                    GROUP BY MEMBER_ID
                    ORDER BY COUNT(*) DESC
                    LIMIT 1)
ORDER BY R.REVIEW_DATE, R.REVIEW_TEXT

간단한 JOIN 문제였다.

 

6. 없어진 기록 찾기

SELECT O.ANIMAL_ID, O.NAME
FROM ANIMAL_INS AS I
RIGHT JOIN ANIMAL_OUTS AS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.ANIMAL_ID IS NULL
ORDER BY O.ANIMAL_ID, O.NAME;

RIGTH JOIN을 해서 입양온 기록이 없어도 입양간 기록에 있다면 테이블에 합쳐지도록 하였다.

 

7. 있었는데요 없었습니다

SELECT I.ANIMAL_ID, I.NAME
FROM ANIMAL_INS AS I
JOIN ANIMAL_OUTS AS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.DATETIME > O.DATETIME
ORDER BY I.DATETIME

WHERE 문으로 간단하게 조건을 설정하면 된다

 

8. 오랜 기간 보호한 동물 (1)

SELECT I.NAME, I.DATETIME
FROM ANIMAL_INS AS I
LEFT JOIN ANIMAL_OUTS AS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE O.ANIMAL_ID IS NULL
ORDER BY I.DATETIME
LIMIT 3;

LIMIT와 LEFT JOIN을 사용하였다

 

9. 보호소에서 중성화한 동물

SELECT I.ANIMAL_ID, I.ANIMAL_TYPE, I.NAME
FROM ANIMAL_INS AS I
JOIN ANIMAL_OUTS AS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.SEX_UPON_INTAKE LIKE 'Intact%' AND (O.SEX_UPON_OUTCOME LIKE 'Neutered%' OR O.SEX_UPON_OUTCOME LIKE 'Spayed%')
ORDER BY I.ANIMAL_ID

간단한 INNER JOIN 문제였다

 

10. 상품 별 오프라인 매출 구하기

SELECT PRODUCT_CODE, PRICE*SUM(SALES_AMOUNT) AS SALES
FROM PRODUCT AS P
JOIN OFFLINE_SALE AS S ON P.PRODUCT_ID = S.PRODUCT_ID
GROUP BY S.PRODUCT_ID
ORDER BY SALES DESC, PRODUCT_CODE

간단한 INNER JOIN 문제였다

 

11. 상품을 구매한 회원 비율 구하기

SELECT YEAR(S.SALES_DATE) AS YEAR, MONTH(S.SALES_DATE) AS MONTH, COUNT(DISTINCT S.USER_ID) AS PUCHASED_USERS, ROUND(COUNT(DISTINCT S.USER_ID) / (SELECT COUNT(*)                                                                                   FROM USER_INFO
                                                WHERE YEAR(JOINED)=2021),1) AS PUCHASED_RATIO
FROM USER_INFO AS U
JOIN ONLINE_SALE AS S ON U.USER_ID = S.USER_ID
WHERE YEAR(U.JOINED)=2021
GROUP BY YEAR, MONTH
ORDER BY YEAR, MONTH

다소 복잡한 걸로 보였지만 중복 가능성을 고려해야 하는 걸 알았다면 그 이후부턴 쉽다

 

2번 문제가 가장 어려웠다

 

'STUDY > MYSQL' 카테고리의 다른 글

MySQL : String, Date 고득점 Kit  (1) 2023.10.21
MySQL : JOIN 연산 + 기본 예제  (0) 2023.10.21
MySQL : IS NULL 문 고득점 Kit  (0) 2023.10.21
MySQL : GROUP BY 문 고득점 Kit  (0) 2023.10.21
MySQL : SUM, MAX, MIN 문 고득점 Kit  (1) 2023.10.20