🐬 SQL/🏆 MySQL 문제풀이

🔓 05. 프로그래머스 LEVEL3 문제풀이

nyamin9 2023. 10. 27. 00:15

모바일은 화면을 돌려 가로화면으로 보시는 게 읽으시기 편할 수 있습니다. 돌려서 보시는 걸 추천드릴게요!!

 

 

원래 문항은 구문에 따라 구분되어 있지만, 알고 푸는 것보다 모르고 푸는 게 재밌을 것 같아 난이도별로 공부하고 있습니다 :)

 


🔑 Q23. 조회수가 가장 많은 중고거래 게시판의 첨부파일 조회하기

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

- CONCAT( ) : 문자열 이어붙이기

- INNER JOIN

- 서브쿼리

SELECT 
CONCAT('/home/grep/src/', F.BOARD_ID, '/', FILE_ID, FILE_NAME, FILE_EXT) AS FILE_PATH
FROM USED_GOODS_BOARD AS B
INNER JOIN USED_GOODS_FILE AS F
ON B.BOARD_ID = F.BOARD_ID 
AND B.VIEWS = (SELECT MAX(VIEWS) FROM USED_GOODS_BOARD)
ORDER BY FILE_ID DESC;

 


🔑 Q24. 조건에 맞는 사용자 정보 조회하기 

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

- CONCAT( ) : 문자열 이어붙이기

- LEFT(COLUMN, 왼쪽에서부터의 자릿수 n) : 왼쪽에서부터 n개의 문자 추출 

- MID(COLUMN, 왼쪽에서부터 자릿수 n, 가져오려는 문자 수 m) : 왼쪽 n번째 자리부터 m개의 문자 추출

- RIGHT(COLUMN, 오른쪽에서부터의 자릿수 n) : 오른쪽에서 n번째 자리부터 끝까지 추출

- INNER JOIN

- 서브쿼리 : 서브쿼리를 조건문 내에 쓸때, 서브쿼리가 추출하는 행이 하나 이상인 경우에는 IN 이랑 같이 사용하기

SELECT DISTINCT(USER_ID), NICKNAME, 
CONCAT(CITY, ' ', STREET_ADDRESS1, ' ', STREET_ADDRESS2) AS 전체주소,
CONCAT(LEFT(TLNO, 3), '-', MID(TLNO, 4, 4), '-', RIGHT(TLNO, 4)) AS 전화번호
FROM USED_GOODS_BOARD AS B
INNER JOIN USED_GOODS_USER AS U
ON B.WRITER_ID = U.USER_ID 
AND B.WRITER_ID IN 
(SELECT WRITER_ID FROM USED_GOODS_BOARD GROUP BY 1 HAVING COUNT(BOARD_ID) >= 3)
ORDER BY 1 DESC;

 


🔑 Q25. 조건에 맞는 사용자와 총 거래금액 조회하기  

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

SELECT USER_ID, NICKNAME, SUM(PRICE) AS TOTAL_SALES
FROM USED_GOODS_BOARD AS B
INNER JOIN USED_GOODS_USER AS U
ON B.WRITER_ID = U.USER_ID
AND B.STATUS = 'DONE'
GROUP BY 1
HAVING TOTAL_SALES >= 700000
ORDER BY 3;

 


🔑 Q27. 대여 기록이 존재하는 자동차 리스트 구하기   

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

☑️ 풀이

SELECT DISTINCT(C.CAR_ID)
FROM CAR_RENTAL_COMPANY_CAR AS C
INNER JOIN CAR_RENTAL_COMPANY_RENTAL_HISTORY AS H
ON C.CAR_ID = H.CAR_ID
AND C.CAR_TYPE = '세단'
AND H.START_DATE LIKE '%-10-%'
ORDER BY 1 DESC;

 


⛔ Q28. 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기    

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

 

- 첫 풀이 : 대여 중인 자동차의 ID를 추출하고, 원래 테이블과 LEFT JOIN하여 대여 가능한 자동차의 정보도 추출하는 쿼리

- 쿼리를 짜는 동안에도 이렇게 짜는 게 맞을까 하는 생각이 들 정도로, 비효율적이였음,,, 아쉽다🥲

WITH TEMP AS 
(
    SELECT CAR_ID,
    CASE
    WHEN (START_DATE) <= '2022-10-16' AND (END_DATE) >= '2022-10-16' THEN '대여중'
    ELSE '대여 가능' END AS AVAILABILITY
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    GROUP BY 1,2
    HAVING AVAILABILITY = '대여중'
    ORDER BY 1 DESC
)

SELECT DISTINCT(H.CAR_ID),
CASE 
WHEN T.AVAILABILITY = '대여중' THEN AVAILABILITY ELSE '대여 가능' END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY AS H
LEFT JOIN TEMP AS T
ON H.CAR_ID = T.CAR_ID
ORDER BY 1 DESC;

 

- 그래서 찾아본 다른 풀이

중첩 CASE WHEN 구문을 사용해서, 중복으로 적용되는 자동차 ID를 식별함

CASE WHEN 구문을 이렇게도 사용할 수 있구나 깨달았다.

두고두고 써먹을 생각이다!!

SELECT CAR_ID, 
CASE WHEN 
SUM(CASE WHEN (START_DATE) <= '2022-10-16' AND (END_DATE) >= '2022-10-16' THEN 1 
    ELSE 0 END) = 1 THEN '대여중' ELSE '대여 가능' END AS AVAILABILITY
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY 1
ORDER BY 1 DESC;

 


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

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

처음 문제를 풀 때, 이해를 잘못해서 한동안 삽질했던 문제이다.

8월부터 10월까지의 총 대여 횟수가 5회 이상인 자동차 들에 대해서, 월별 대여 횟수를 구하는 문제이다. 그런데 처음 문제를 봤을 때는 월별 대여 횟수가 5회 이상인 자동차 라고 이해를 해버렸다... 나중에 코테를 볼때나 현업에서 문제를 해결할 때에도, 워딩 하나하나에 집중해야겠다고 생각했다.

SELECT MONTH(START_DATE) AS MONTH, CAR_ID, COUNT(HISTORY_ID) AS RECORDS
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE START_DATE BETWEEN '2022-08-01' AND '2022-10-31'
AND CAR_ID IN 
(
    SELECT CAR_ID FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE START_DATE BETWEEN '2022-08-01' AND '2022-10-31'
    GROUP BY 1 HAVING COUNT(HISTORY_ID) >= 5
)
GROUP BY 1,2
ORDER BY 1, 2 DESC;

 


🔑 Q30. 카테고리 별 도서 판매량 집계하기    

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

SELECT CATEGORY, SUM(SALES) AS TOTAL_SALES
FROM BOOK AS B
INNER JOIN BOOK_SALES AS S
ON B.BOOK_ID = S.BOOK_ID
WHERE S.SALES_DATE LIKE '2022-01-%'
GROUP BY 1
ORDER BY 1;

 


⛔ Q31. 즐겨찾기가 가장 많은 식당 정보 출력하기    

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

- 단순해 보여서 부담 없이 푼 문제인데, 생각지 못한 부분이 걸려서 당황한 문제였다.

SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM REST_INFO
WHERE (FOOD_TYPE, FAVORITES) IN 
(
    SELECT FOOD_TYPE, MAX(FAVORITES) AS FAVORITES
    FROM REST_INFO
    GROUP BY 1
)
ORDER BY 1 DESC;

 


🔑 Q32. 조건별로 분류하여 주문상태 출력하기     

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

SELECT ORDER_ID, PRODUCT_ID, DATE_FORMAT(OUT_DATE, '%Y-%m-%d') AS OUT_DATE, 
CASE
WHEN OUT_DATE <= '2022-05-01' THEN '출고완료'
WHEN OUT_DATE IS NULL THEN '출고미정'
ELSE '출고대기' END AS 출고여부
FROM FOOD_ORDER
ORDER BY 1;

 


🔑 Q33. 헤비 유저가 소유한 장소      

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

SELECT ID, NAME, HOST_ID
FROM PLACES
WHERE HOST_ID IN
(
    SELECT HOST_ID FROM PLACES
    GROUP BY 1 HAVING COUNT(ID) >= 2
)
ORDER BY 1;

 


🔑 Q34. 오랜 기간 보호한 동물(2)       

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

- GROUP BY를 사용해서 한번 묶어두면, ORDER BY에서 정렬 기준을 정할 때 그냥 집계함수 사용하면 됨 

SELECT I.ANIMAL_ID, I.NAME
FROM ANIMAL_INS AS I
INNER JOIN ANIMAL_OUTS AS O
ON I.ANIMAL_ID = O.ANIMAL_ID
GROUP BY 1
ORDER BY DATEDIFF(O.DATETIME, I.DATETIME) DESC LIMIT 2;

 


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

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

- LEFT JOIN : 한쪽 테이블에는 있지만, 다른 테이블에는 없는 정보를 찾을 때 사용함. IS NULL 함수와 묶어서 생각하기.

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.DATETIME IS NULL
ORDER BY 2 LIMIT 3;

 


🔑 Q36. 있었는데요 없었습니다      

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

☑️ 풀이

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

 


🔑 Q37. 없어진 기록 찾기      

 

☑️ 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

☑️ 풀이

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