Algorithm/Programmers SQL

[MySQL] 프로그래머스 그룹별 조건에 맞는 식당 목록 출력하기

제우제우 2024. 9. 19. 14:38

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

 

프로그래머스

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

programmers.co.kr

코딩테스트 연습 > JOIN > 그룹별 조건에 맞는 식당 목록 출력하기

 

문제 분석

난이도: LEVEL4

 

문제 요구사항

MEMBER_PROFILE와 REST_REVIEW 테이블에서 리뷰를 가장 많이 작성한 회원의 리뷰들을 조회하는 SQL문을 작성해주세요. 

회원 이름, 리뷰 텍스트, 리뷰 작성일이 출력되도록 작성해주시고, 결과는 리뷰 작성일을 기준으로 오름차순, 리뷰 작성일이 같다면 리뷰 텍스트를 기준으로 오름차순 정렬해주세요.

 

정답 코드 1

WITH MAX_REVIEW AS ( -- 회원이 작성한 가장 많은 리뷰 수
    SELECT COUNT(*) COUNT 
    FROM REST_REVIEW 
    GROUP BY MEMBER_ID 
    ORDER BY 1 DESC 
    LIMIT 1
),
MAX_REVIEW_MEMBER AS ( -- 가장 많은 리뷰를 작성한 회원(들) 
    SELECT MEMBER_ID 
    FROM REST_REVIEW R
    GROUP BY MEMBER_ID
    HAVING COUNT(*) = (SELECT * FROM MAX_REVIEW)
)
SELECT P.MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE, '%Y-%m-%d') REVIEW_DATE
FROM MEMBER_PROFILE P JOIN MAX_REVIEW_MEMBER M
ON P.MEMBER_ID = M.MEMBER_ID 
JOIN REST_REVIEW R ON R.MEMBER_ID = M.MEMBER_ID 
ORDER BY 3, 2

 

MAX_REVIEW CTE: 각 회원들이 가장 많이 작성한 리뷰 수 구하기

MAX_REVIEW_MEMEBER CTE: 가장 많인 리뷰 수를 작성한 회원(들) 구하기 결과는 1명 이상 

 

MEMBER_PROFILE, MAX_REVIEW_MEMBER, REST_REVIEW 3개의 테이블을 MEMBER_ID를 기준으로 조인 

조인 데이터는 MAX_REVIEW_MEMBER가 가장 적을테니 해당 테이블의 MEMBER_ID를 기준으로 조인을 시작했다. 

 

정렬은 리뷰 날짜(REVIEW_DATE) 기준으로 오름차순, REVIEW_TEXT 기준으로 오름차순 (사전 순서)

 

MAX_REVIEW CTE 없이 MAX_REVIEW_MEMBER에서 HAVING절 서브 쿼리에 넣을 순 있지만 

GROUP BY 결과에 매번 GROUP BY COUNT(*) 쿼리가 나가니 성능상 좋지 않다. 그래서 CTE로 따로 처리하고

단일 ROW 결과만 가져오게 하였다.

 

정답 코드 2

WITH MEMBER_RANK AS (
    SELECT MEMBER_ID, RANK() OVER (ORDER BY COUNT(MEMBER_ID) DESC) RNK
    FROM REST_REVIEW
    GROUP BY MEMBER_ID 
)
SELECT MEMBER_NAME,	REVIEW_TEXT, DATE_FORMAT(REVIEW_DATE, '%Y-%m-%d') REVIEW_DATE
FROM MEMBER_RANK RA JOIN MEMBER_PROFILE P 
ON RA.MEMBER_ID = P.MEMBER_ID 
JOIN REST_REVIEW R ON R.MEMBER_ID = P.MEMBER_ID 
WHERE RA.RNK = 1
ORDER BY 3, 2

 

RANK() 활용 풀이