Post

그룹별 조건에 맞는 식당 목록 출력하기

JOIN

그룹별 조건에 맞는 식당 목록 출력하기


문제 설명

다음은 고객의 정보를 담은 MEMBER_PROFILE 테이블과 식당의 리뷰 정보를 담은 REST_REVIEW 테이블입니다.


MEMBER_PROFILE 테이블

Column nameTypeNullableDescription
MEMBER_IDVARCHAR(100)FALSE회원 ID
MEMBER_NAMEVARCHAR(50)FALSE회원 이름
TLNOVARCHAR(50)TRUE회원 연락처
GENDERVARCHAR(1)TRUE성별
DATE_OF_BIRTHDATETRUE생년월일


REST_REVIEW 테이블

Column nameTypeNullableDescription
REVIEW_IDVARCHAR(10)FALSE리뷰 ID
REST_IDVARCHAR(10)TRUE식당 ID
MEMBER_IDVARCHAR(100)TRUE회원 ID
REVIEW_SCORENUMBERTRUE리뷰 점수
REVIEW_TEXTVARCHAR(1000)TRUE리뷰 텍스트
REVIEW_DATEDATETRUE리뷰 작성일




문제

MEMBER_PROFILE와 REST_REVIEW 테이블에서 리뷰를 가장 많이 작성한 회원의 리뷰들을 조회하는 SQL문을 작성해주세요. 회원 이름, 리뷰 텍스트, 리뷰 작성일이 출력되도록 작성해주시고, 결과는 리뷰 작성일을 기준으로 오름차순, 리뷰 작성일이 같다면 리뷰 텍스트를 기준으로 오름차순 정렬해주세요. REVIEW_DATE의 데이트 포맷이 예시와 동일해야 정답처리 됩니다. (예시 : YYYY-MM-DD)




풀이 과정
  1. 조건 확인
    • MEMBER_ID 기준 리뷰를 가장 많이 작성한 회원의 리뷰 데이터 조회
    • REVIEW_DATE의 데이트 포맷은 YYYY-MM-DD
  2. 리뷰를 가장 많이 작성한 회원 찾기
    • REST_REVIEW 테이블에서 회원별 리뷰 개수를 그룹화하여, 가장 많은 리뷰를 작성한 회원 찾기
    • 이를 위해 GROUP BY MEMBER_ID를 사용하여 회원별 리뷰 개수를 계산하고, COUNT(*)로 로 각 회원의 리뷰 개수를 집계
    • ORDER BY COUNT(*) DESC로 리뷰 개수가 가장 많은 회원을 찾고, FETCH FIRST 1 ROWS ONLY로 상위 한 명만 선택
  3. 테이블 결합 (JOIN)
    • INNSER JOIN 선택 이유 : 리뷰를 쓴 회원이여야 하므로 두 테이블 모두에 존재하는 MEMBER_ID 여야 하기 때문
  4. 결과 정렬
    • 정렬 기준에 따라 ORDER BY로 결과 정렬
      • 리뷰 작성일(REVIEW_DATE)를 기준으로 오름차순
      • 리뷰 작성일이 같다면 REVIEW_TEXT 기준 오름차순
  5. 최종 결과 출력
    • 최종적으로 회원 이름(MEMBER_NAME), 리뷰 텍스트(REVIEW_TEXT), 리뷰 작성일(REVIEW_DATE)만 출력
    • TO_CHAR(REVIEW_DATE, ‘YYYY-MM-DD’)를 사용하여 날짜를 YYYY-MM-DD 형식의 문자열로 변환
  • 교훈
    • 서브쿼리 활용해서 특정 조건에 맞는 데이터를 먼저 필터링한 후 메인 쿼리에서 결합하는 것… 자주 쓰임.
    • 익숙하지 않은 FETCH FIRST 숫자 ROWS ONLY.. 기존에 쓰던 ROWNUM만이 자꾸 떠오른다…..




정답

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SELECT
    MP.MEMBER_NAME,
    RR.REVIEW_TEXT,
    TO_CHAR(RR.REVIEW_DATE, 'YYYY-MM-DD') AS REVIEW_DATE
FROM
    MEMBER_PROFILE MP
JOIN
    REST_REVIEW RR
ON
    MP.MEMBER_ID = RR.MEMBER_ID
WHERE
    RR.MEMBER_ID = (
        SELECT MEMBER_ID
        FROM REST_REVIEW
        GROUP BY MEMBER_ID
        ORDER BY COUNT(*) DESC
        FETCH FIRST 1 ROWS ONLY
    )
ORDER BY
    RR.REVIEW_DATE ASC,
    RR.REVIEW_TEXT ASC;  


Tip

  1. 가장 리뷰를 많이 작성한 회원 조회
    • 서브쿼리로 가장 리뷰를 많이 작성한 회원의 ID를 찾고, 이를 기반으로 필요한 데이터를 JOIN하여 조회
      • GROUP BY MEMBER_ID: MEMBER_ID로 그룹화합니다.
      • ORDER BY COUNT(*) DESC: 리뷰 개수가 많은 순서대로 정렬합니다.
      • FETCH FIRST 1 ROWS ONLY: 가장 상위의 한 행만 가져옵니다.
  2. DATE 타입 형식 맞추기
    • TO_CHAR(컬럼명, ‘YYYY-MM-DD’) = ‘YYYY-MM-DD’ (VARCHAR 타입으로 변경됨)

SQL Dialect Used: Oracle




개념 확인

  • INNER JOIN
    • 두 테이블의 공통된 값을 기준으로 데이터를 연결
    • 양쪽 테이블 모두에 일치하는 행만 결과에 포함됨
  • TO_CHAR 함수
    • 날짜 또는 숫자를 문자열 형식으로 변환
  • GROUP 함수
    • 특정 컬럼 값을 기준으로 데이터를 그룹화하여 집계 계산 수행
      • COUNT(*)은 해당 그룹의 모든 행을, COUNT(컬럼명)은 NULL이 아닌 값 개수를 계산
      • ORDER BY COUNT() : COUNT로 집계된 값에 따라 결과를 정렬
  • FETCH FIRST n ROWS ONLY
    • 결과에서 상위 n개의 행만 가져오는 절
    • Oracle 12c 이상에서는 이 구문을 사용하며, Oracle 11g 이하에서는 ROWNUM <= 3로 대체할 수 있음
    • MYSQL에서는 LIMIT n;




그룹별 조건에 맞는 식당 목록 출력하기

This post is licensed under Park Juyoung by the author.

Trending Tags