Dev Hyeri

◖코딩 테스트◗▬▬▬▬▬▬▬▬▬/프로그래머스

[SQL KIT] (2024) 그룹별 조건에 맞는 식당 목록 출력하기(설명/코드/정답)

_hyeri 2024. 2. 2. 20:44

 

문제 링크 : 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