https://school.programmers.co.kr/learn/courses/30/lessons/131124
코딩테스트 연습 > 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() 활용 풀이
'Algorithm > Programmers SQL' 카테고리의 다른 글
[MySQL] 프로그래머스 5월 식품들의 총매출 조회하기 (0) | 2024.09.19 |
---|---|
[MySQL] 프로그래머스 그룹별 조건에 맞는 식당 목록 출력하기 (0) | 2024.09.19 |
[MySQL] 프로그래머스 오프라인/온라인 판매 데이터 통합하기 (0) | 2024.09.18 |
[MySQL] 프로그래머스 오프라인/온라인 판매 데이터 통합하기 (1) | 2024.09.18 |
[MySQL] 프로그래머스 취소되지 않은 진료 예약 조회하기 (1) | 2024.09.18 |