inblog logo
|
jjack1
    프로그래머스MySQL코딩테스트

    [프로그래머스] (MySQL) 88. 그룹별 조건에 맞는 식당 목록 출력하기

    최재원's avatar
    최재원
    Jan 07, 2026
    [프로그래머스] (MySQL) 88. 그룹별 조건에 맞는 식당 목록 출력하기
    💡

    문제 설명

    다음은 고객의 정보를 담은 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_TEXTREVIEW_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문을 작성해주세요. 회원 이름, 리뷰 텍스트, 리뷰 작성일이 출력되도록 작성해주시고, 결과는 리뷰 작성일을 기준으로 오름차순, 리뷰 작성일이 같다면 리뷰 텍스트를 기준으로 오름차순 정렬해주세요.

    예시

    MEMBER_PROFILE 테이블이 다음과 같고
    MEMBER_ID
    MEMBER_NAME
    TLNO
    GENDER
    DATE_OF_BIRTH
    jiho92@naver.com
    이지호
    01076432111
    W
    1992-02-12
    jiyoon22@hotmail.com
    김지윤
    01032324117
    W
    1992-02-22
    jihoon93@hanmail.net
    김지훈
    01023258688
    M
    1993-02-23
    seoyeons@naver.com
    박서연
    01076482209
    W
    1993-03-16
    yelin1130@gmail.com
    조예린
    01017626711
    W
    1990-11-30
    REST_REVIEW 테이블이 다음과 같을 때
    REVIEW_ID
    REST_ID
    MEMBER_ID
    REVIEW_SCORE
    REVIEW_TEXT
    REVIEW_DATE
    R000000065
    00028
    soobin97@naver.com
    5
    부찌 국물에서 샤브샤브 맛이나고 깔끔
    2022-04-12
    R000000066
    00039
    yelin1130@gmail.com
    5
    김치찌개 최곱니다.
    2022-02-12
    R000000067
    00028
    yelin1130@gmail.com
    5
    햄이 많아서 좋아요
    2022-02-22
    R000000068
    00035
    ksyi0316@gmail.com
    5
    숙성회가 끝내줍니다.
    2022-02-15
    R000000069
    00035
    yoonsy95@naver.com
    4
    비린내가 전혀없어요.
    2022-04-16
    SQL을 실행하면 다음과 같이 출력되어야 합니다.
    MEMBER_NAME
    REVIEW_TEXT
    REVIEW_DATE
    조예린
    김치찌개 최곱니다.
    2022-02-12
    조예린
    햄이 많아서 좋아요
    2022-02-22

    주의사항

    REVIEW_DATE의 데이트 포맷이 예시와 동일해야 정답처리 됩니다.
     

    코드 - in 을 사용한 방법

    SELECT MP.MEMBER_NAME, RR.REVIEW_TEXT, DATE_FORMAT(RR.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE FROM REST_REVIEW RR INNER JOIN MEMBER_PROFILE MP ON RR.MEMBER_ID = MP.MEMBER_ID WHERE RR.MEMBER_ID IN ( SELECT MEMBER_ID FROM ( SELECT MEMBER_ID, RANK() OVER (ORDER BY COUNT(*) DESC) AS RANK_NUM FROM REST_REVIEW GROUP BY MEMBER_ID ) REVIEW WHERE RANK_NUM = 1 ) ORDER BY RR.REVIEW_DATE ASC, RR.REVIEW_TEXT ASC;
    notion image

    코드 - 서브쿼리 & join 을 사법

    SELECT MP.MEMBER_NAME, RR.REVIEW_TEXT, DATE_FORMAT(RR.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE FROM REST_REVIEW RR JOIN MEMBER_PROFILE MP ON MP.MEMBER_ID = RR.MEMBER_ID JOIN ( SELECT MEMBER_ID FROM REST_REVIEW GROUP BY MEMBER_ID HAVING COUNT(*) = ( SELECT MAX(cnt) FROM ( SELECT COUNT(*) AS cnt FROM REST_REVIEW GROUP BY MEMBER_ID ) t ) ) TOPPER ON TOPPER.MEMBER_ID = RR.MEMBER_ID ORDER BY RR.REVIEW_DATE ASC, RR.REVIEW_TEXT ASC;
     

    두 방식의 차이점

    구분
    첫 번째 쿼리 (RANK)
    두 번째 쿼리 (HAVING = MAX)
    핵심 방식
    RANK() OVER (ORDER BY COUNT(*) DESC) 사용
    HAVING COUNT(*) = (SELECT MAX(cnt) …) 사용
    의존 기능
    윈도 함수 필요 (MySQL 8.0 이상)
    집계와 서브쿼리만 사용 (MySQL 5.7도 가능)
    계산 구조
    한 번의 GROUP BY + 윈도 함수
    GROUP BY 두 번 수행 (내부·외부)
    성능
    상대적으로 효율적 (집계 1회)
    중첩 집계로 약간 비효율적
    조인 형태
    WHERE … IN (subquery) 세미조인
    명시적 JOIN (파생 테이블 결합)
    가독성
    직관적, 짧음
    더 길고 중첩 많음
    이식성
    낮음 (윈도 함수 미지원 DB 불가)
    높음 (모든 주요 DB 지원)
    결과
    동점자 모두 반환
    동일
    추천 상황
    MySQL 8.0 이상 환경
    MySQL 5.7 이하, 호환성 중시
    요약:
    • 최신 MySQL이면 RANK() 쿼리가 빠르고 간결하다.
    • 구버전이나 타 DB 호환을 원하면 HAVING = MAX 쿼리가 안전하다.
     

    힌트

    WITH CustomerCounts AS ( -- 1. 고객별 주문 건수를 계산하고 순위를 매기는 CTE (Common Table Expression) SELECT customer_id, COUNT(*) AS order_count, -- 주문 건수에 따라 순위(rank_num)를 매김. 동률은 같은 순위 부여. RANK() OVER (ORDER BY COUNT(*) DESC) AS rank_num FROM Orders GROUP BY customer_id ) SELECT T1.* -- Orders 테이블의 모든 주문 정보 (T1) FROM Orders T1 INNER JOIN CustomerCounts T2 ON T1.customer_id = T2.customer_id -- 주문 정보와 순위 정보를 고객 ID로 연결 WHERE T2.rank_num = 1; -- 순위가 1인 (가장 많은 주문을 한) 고객의 주문만 선택
    • 주문테이블에서 가장많은 주문을 한 고객의 모든 주문정보
    • 동률도 찾아줌
     
    Share article

    jjack1

    RSS·Powered by Inblog