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

 

프로그래머스

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

programmers.co.kr

코드설명

INNER JOIN + SUBQUERY + GROUP BY + HAVING + COUNT(*) 를 활용합니다.

 

코드

정답코드입니다.

SELECT MP.MEMBER_NAME, RR.REVIEW_TEXT, DATE_FORMAT(RR.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
FROM MEMBER_PROFILE AS MP
INNER JOIN REST_REVIEW AS RR
ON MP.MEMBER_ID = RR.MEMBER_ID
INNER JOIN (SELECT MEMBER_ID FROM REST_REVIEW GROUP BY MEMBER_ID HAVING COUNT(*) = (SELECT COUNT(*) FROM REST_REVIEW GROUP BY MEMBER_ID ORDER BY COUNT(*) DESC LIMIT 1)) AS RR2
ON RR.MEMBER_ID = RR2.MEMBER_ID
ORDER BY RR.REVIEW_DATE ASC, RR.REVIEW_TEXT ASC

 

 

처음에 틀린 접근방법입니다. 이 코드의 경우 INNER JOIN RR이 GROUP BY 로 1개만 나오기에 모든 리뷰 목록을 구하지 못합니다.

-- 코드를 입력하세요
SELECT MP.MEMBER_NAME, RR.REVIEW_TEXT, DATE_FORMAT(RR.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
FROM MEMBER_PROFILE AS MP
INNER JOIN (SELECT MEMBER_ID, REVIEW_TEXT, REVIEW_DATE FROM REST_REVIEW GROUP BY MEMBER_ID HAVING COUNT(*) = (SELECT COUNT(*) FROM REST_REVIEW GROUP BY MEMBER_ID ORDER BY COUNT(*) DESC LIMIT 1)) AS RR
ON MP.MEMBER_ID = RR.MEMBER_ID
ORDER BY RR.REVIEW_DATE ASC, RR.REVIEW_TEXT ASC

 

ORACLE

이 쿼리는 반만 정답입니다. 이유는 리뷰를 가장 많이 작성한 사람'들' 이 아닌 가장 많이 작성한 1명만 반환하기 때문입니다.ㅋ

SELECT MP.MEMBER_NAME, RR.REVIEW_TEXT, TO_CHAR(RR.REVIEW_DATE, 'YYYY-MM-DD')
FROM MEMBER_PROFILE MP
INNER JOIN (SELECT MEMBER_ID, REVIEW_TEXT, REVIEW_DATE
FROM REST_REVIEW 
WHERE MEMBER_ID = (
    SELECT MEMBER_ID
    FROM ( 
        SELECT MEMBER_ID
        FROM REST_REVIEW
        GROUP BY MEMBER_ID
        ORDER BY COUNT(*) DESC    
   ) WHERE ROWNUM = 1
) ) RR
ON MP.MEMBER_ID = RR.MEMBER_ID
ORDER BY RR.REVIEW_DATE ASC, RR.REVIEW_TEXT ASC

 

 

아래의 INNER JOIN만으로도 처리가 가능하다.사실상 SUBQUERY를 사용하나 INNER JOIN을 사용하나 본질적으로는 같다.

그리고 사실 위의 쿼리보다는 이 쿼리가 더 맞다. 이유는 이 쿼리의 경우 만약 가장 많이 리뷰를 작성한 사람이 3명일경우에도 처리가 가능하다.

SELECT MP.MEMBER_NAME, RR.REVIEW_TEXT, TO_CHAR(RR.REVIEW_DATE, 'YYYY-MM-DD')
FROM MEMBER_PROFILE MP
INNER JOIN (SELECT MEMBER_ID, COUNT(*) AS COUNT
FROM REST_REVIEW
GROUP BY MEMBER_ID) TB1
ON MP.MEMBER_ID = TB1.MEMBER_ID
INNER JOIN ( SELECT MAX(COUNT(*)) AS COUNT
FROM REST_REVIEW
GROUP BY MEMBER_ID ) TB2
ON TB1.COUNT = TB2.COUNT
INNER JOIN REST_REVIEW RR
ON MP.MEMBER_ID = RR.MEMBER_ID
ORDER BY RR.REVIEW_DATE ASC, RR.REVIEW_TEXT ASC

만약 이 위의 4중 JOIN 문의 JOIN을 줄이고 싶다면, MAX(COUNT(*)) 값을 서브쿼리로 구해서 REST_REVIEW 값에 넣어주면 될 것 입니다.

 

 

이 쿼리도 INNER JOIN 을 3개하는 대신 2개로 바꾸고 서브쿼리에 값을 넣은것이다.

SELECT MP.MEMBER_NAME, RR.REVIEW_TEXT, TO_CHAR(RR.REVIEW_DATE, 'YYYY-MM-DD')
FROM MEMBER_PROFILE MP
INNER JOIN (SELECT MEMBER_ID, COUNT(*) AS COUNT
FROM REST_REVIEW
GROUP BY MEMBER_ID
HAVING COUNT(*) = (SELECT MAX(COUNT(*)) AS COUNT
FROM REST_REVIEW
GROUP BY MEMBER_ID )) TB1
ON MP.MEMBER_ID = TB1.MEMBER_ID
INNER JOIN REST_REVIEW RR
ON MP.MEMBER_ID = RR.MEMBER_ID
ORDER BY RR.REVIEW_DATE ASC, RR.REVIEW_TEXT ASC

+ Recent posts