문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/131124
정상 코드.
방법 1 윈도우 함수사용. 리뷰 많이 쓴 MEMBER_ID 찾기
SELECT MEMBER_NAME, REVIEW_TEXT,
DATE_FORMAT(REVIEW_DATE,'%Y-%m-%d') AS REVIEW_DATE
FROM MEMBER_PROFILE JOIN REST_REVIEW USING (MEMBER_ID)
WHERE MEMBER_ID IN (SELECT MEMBER_ID
FROM (SELECT *, DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS REVIEW_RANK
FROM REST_REVIEW
GROUP BY MEMBER_ID) INLINE
WHERE REVIEW_RANK = 1
)
ORDER BY REVIEW_DATE, REVIEW_TEXT
방법 2 CTE, 윈도우 함수사용. 많이 쓴 리뷰 수 카운팅
WITH REST_REVIEW_WITH_COUNT AS (
SELECT MEMBER_ID, REVIEW_TEXT, REVIEW_DATE,
COUNT(*) OVER (PARTITION BY MEMBER_ID) AS REVIEW_COUNT
FROM REST_REVIEW
)
SELECT MEMBER_NAME, REVIEW_TEXT,
DATE_FORMAT(REVIEW_DATE,'%Y-%m-%d') AS REVIEW_DATE
FROM REST_REVIEW_WITH_COUNT JOIN MEMBER_PROFILE USING(MEMBER_ID)
WHERE REVIEW_COUNT = (SELECT MAX(REVIEW_COUNT)
FROM REST_REVIEW_WITH_COUNT)
ORDER BY REVIEW_DATE, REVIEW_TEXT
내부 동작 순서 (방법 1)
1. FROM 절
MEMBER_PROFILE 테이블과 REST_REVIEW 테이블을 MEMBER_ID를 사용하여 조인합니다.
2. WHERE 절
MEMBER_ID가 서브쿼리에서 선택된 값 중 하나인 행만 선택합니다.
서브쿼리에서는 REST_REVIEW 테이블을 이용하여 각 MEMBER_ID에 대해 리뷰 수를 세고, DENSE_RANK() 함수를 사용하여 리뷰 수에 따른 랭크를 부여합니다. 이때 DENSE_RANK()를 이용하여 리뷰 수가 같은 경우에도 같은 순위를 부여합니다.
최종적으로 REVIEW_RANK가 1인 회원들의 MEMBER_ID를 선택합니다.
서브쿼리
SELECT MEMBER_ID
FROM (SELECT *, DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS REVIEW_RANK
FROM REST_REVIEW
GROUP BY MEMBER_ID) INLINE
WHERE REVIEW_RANK = 1
실행 결과
3. SELECT 절
MEMBER_NAME, REVIEW_TEXT, REVIEW_DATE를 선택합니다.
REVIEW_DATE는 DATE_FORMAT 함수를 사용하여 날짜 형식을 변경합니다.
4. ORDER BY 절
결과를 REVIEW_DATE, REVIEW_TEXT 순서로 정렬합니다.
쿼리 작성 중 발생할 수 있는 실수.
- 그룹별 리뷰 수 출력 결과 동일 순위 발생 확인
- 실행 결과 9개의 행이 나와야 한다
SELECT MEMBER_ID, COUNT(*)
FROM REST_REVIEW
GROUP BY MEMBER_ID
ORDER BY 2 DESC
실행 결과. 아이디 ksjs1115@gmail.com, minjea985@naver.com, soso94@naver.com 는 리뷰를 3개씩 작성함
주의. 잘못 작성된 쿼리 정답 처리 가능성 있음. (아래 예시 테이블 참고)
--> 실행 결과 검증 습관 필요
초기 코드
SELECT MEMBER_NAME, REVIEW_TEXT,
DATE_FORMAT(REVIEW_DATE,'%Y-%m-%d') AS REVIEW_DATE
FROM MEMBER_PROFILE JOIN REST_REVIEW USING (MEMBER_ID)
WHERE MEMBER_ID IN (SELECT MEMBER_ID
FROM REST_REVIEW
GROUP BY MEMBER_ID
HAVING COUNT(*) = (SELECT MAX(CNT) AS MAX_CNT
FROM(SELECT *, COUNT(*) AS CNT
FROM REST_REVIEW
GROUP BY MEMBER_ID
ORDER BY COUNT(*) DESC
) INLINE
)
)
ORDER BY REVIEW_DATE, REVIEW_TEXT
=>정상 출력
하지만 쿼리 가독성 개선 가능성 있음
MEMBER_NAME | REVIEW_TEXT | REVIEW_DATE |
정소율 | 쫄깃하면서도 육즙이 팡 터지는 맛이 아주 좋았어요. | 2022-01-14 |
김민재 | 안에 찰밥이 들어있는건지 속 내용물이 특히 맛있었어요 | 2022-02-18 |
김민재 | 사람들이 왜 이 음식점을 찬양하는지 알것도 같다 | 2022-02-21 |
정소율 | 순대국은 얼큰한 스타일로 나옴 | 2022-03-11 |
김민재 | 삼겹보다 목살이 더 두껍게 잘라주시는데 씹을 때마다 육즙이 ㅜㅜ 환상 | 2022-03-15 |
정소율 | 쟁반국수와 감자전도 추천 | 2022-03-22 |
김서준 | 끝도 없이 주셔서 배터졌음 그리고 등푸른생선류 넘 맛있음 | 2022-04-11 |
김서준 | 우리가 흔히 생각하는 떡볶이랑은 맛이 사뭇 달라요 | 2022-04-16 |
김서준 | 바삭바삭해요 | 2022-05-23 |
'◖코딩 테스트◗▬▬▬▬▬▬▬▬▬ > 프로그래머스' 카테고리의 다른 글
[SQL KIT] (2024) 자동차 대여 기록 별 대여 금액 구하기(설명/코드/정답) (0) | 2024.02.08 |
---|---|
[SQL KIT] (2024) 자동차 대여 기록에서 장기/단기 대여 구분하기(설명/코드/정답) (0) | 2024.02.05 |
[프로그래머스] 속도 2배, 단축키(shortcuts, hot key) (0) | 2024.02.01 |
[SQL KIT] (2024)특정 기간동안 대여 가능한 자동차들의 대여비용 구하기(설명/코드/정답) (0) | 2024.01.29 |
[SQL KIT] (2024) NULL 처리하기(설명/코드/정답) (0) | 2024.01.27 |