다음은 고객의 정보를 담은 MEMBER_PROFILE테이블과 식당의 리뷰 정보를 담은 REST_REVIEW 테이블입니다. MEMBER_PROFILE 테이블은 다음과 같으며 MEMBER_ID, MEMBER_NAME, TLNO, GENDER, DATE_OF_BIRTH는 회원 ID, 회원 이름, 회원 연락처, 성별, 생년월일을 의미합니다.
Column_name | Type | Nullable |
---|---|---|
MEMBER_ID | VARCHAR(100) | FALSE |
MEMBER_NAME | VARCHAR(50) | FALSE |
TLNO | VARCHAR(50) | TRUE |
GENDER | VARCHAR(1) | TRUE |
DATE_OF_BIRTH | DATE | TRUE |
REST_REVIEW 테이블은 다음과 같으며 REVIEW_ID, REST_ID, MEMBER_ID, REVIEW_SCORE, REVIEW_TEXT,REVIEW_DATE는 각각 리뷰 ID, 식당 ID, 회원 ID, 점수, 리뷰 텍스트, 리뷰 작성일을 의미합니다.
Column_name | Type | Nullable |
---|---|---|
REVIEW_ID | VARCHAR(10) | FALSE |
REST_ID | VARCHAR(10) | TRUE |
MEMBER_ID | VARCHAR(100) | TRUE |
REVIEW_SCORE | NUMBER | TRUE |
REVIEW_TEXT | VARCHAR(1000) | TRUE |
REVIEW_DATE | DATE | TRUE |
MEMBER_PROFILE와 REST_REVIEW 테이블에서 리뷰를 가장 많이 작성한 회원의 리뷰들을 조회하는 SQL문을 작성해주세요. 회원 이름, 리뷰 텍스트, 리뷰 작성일이 출력되도록 작성해주시고, 결과는 리뷰 작성일을 기준으로 오름차순, 리뷰 작성일이 같다면 리뷰 텍스트를 기준으로 오름차순 정렬해주세요.
처음엔 REST_REVIEW 테이블에서 리뷰를 가장 많이 작성한 회원을 찾기 위해서
ID 별(그룹) SELECT COUNT(리뷰 수) 를 했었는데 그렇게 묶는 순간 모든 리뷰들이 묶여서 사용할 수 없게 되는 문제가 있었고
조건절에 서브쿼리를 넣어서 리뷰수가 가장 많았던 ID를 찾아 해당 아이디를 가진 게시글만 조회하도록 코드를 작성해 풀 수 있었다.
나의 풀이
SELECT m.MEMBER_NAME, r.REVIEW_TEXT, DATE_FORMAT(REVIEW_DATE, "%Y-%m-%d") REVIEW_DATE FROM (SELECT MEMBER_ID, MEMBER_NAME FROM MEMBER_PROFILE WHERE MEMBER_ID = (SELECT MEMBER_ID FROM REST_REVIEW GROUP BY MEMBER_ID ORDER BY COUNT(*) DESC LIMIT 1) ) m JOIN (SELECT REVIEW_TEXT, REVIEW_DATE, MEMBER_ID FROM REST_REVIEW ) r ON m.MEMBER_ID = r.MEMBER_ID ORDER BY REVIEW_DATE, REVIEW_TEXT
정답 공유1 - 리뷰 개수가 가장 많은 사람이 한명일 때.
SELECT c.member_name , a.review_text , date_format(a.review_date, '%Y-%m-%d') FROM rest_review a INNER JOIN (SELECT member_id FROM rest_review GROUP BY member_id ORDER BY COUNT(*) DESC LIMIT 1) b ON a.member_id = b.member_id LEFT JOIN member_profile c ON a.member_id = c.member_id ORDER BY a.review_date, a.review_text
정답 공유2. - 리뷰 개수가 가장 많은 회원이 2 이상일 때
WITH MAX_MEMBER AS (SELECT MEMBER_ID FROM REST_REVIEW GROUP BY MEMBER_ID HAVING COUNT(*) = (SELECT COUNT(*) AS MAX_COUNT FROM REST_REVIEW GROUP BY MEMBER_ID ORDER BY COUNT(*) DESC LIMIT 1) ) SELECT M.MEMBER_NAME, R.REVIEW_TEXT, DATE_FORMAT(R.REVIEW_DATE,'%Y-%m-%d') FROM REST_REVIEW R JOIN MAX_MEMBER MM ON R.MEMBER_ID = MM.MEMBER_ID LEFT JOIN MEMBER_PROFILE M ON R.MEMBER_ID = M.MEMBER_ID ORDER BY R.REVIEW_DATE, R.REVIEW_TEXT
성율님 정답
SELECT m.member_name, r.review_text, date_format(r.review_date,'%Y-%m-%d') review_date FROM member_profile m join rest_review r on m.member_id=r.member_id join (SELECT m.member_id, count(r.member_id) FROM member_profile m join rest_review on m.member_id = r.member_id group by m.member_id order by 2 desc limit 1) a on r.member_id = a.member_id order by 3,2
나는 잘 풀었다고 생각했는데 이 쿼리를 보고서 머리를 한 대 얻어 맞은 느낌이었다.
내 쿼리와 이 쿼리의 차이점은 위에 적어놓은 대로 글을 가장 많이 쓴 사람이 한 사람이 아닐 경우에는 해당 사람들의 글들을 전부 가져오도록 sql 쿼리를 작성한 것인데, 나는 이 부분은 고려하지 않고 풀었었다.
아직 left JOIN 개념이 잘 안 잡혀서 다른 사람이 푼 left join 사용구문을
잘 이해하지 못하겠다. 조금 더 정진하도록!