본문 바로가기

Skill Sets/SQL

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

SMALL

안녕하세요! 데코입니다!

 

오늘은 프로그래머스 코딩테스트 연습에 있는 "그룹별 조건에 맞는 식당 목록 출력하기" 문제를 포스팅하려고 합니다!

 

바로 포스팅 시작할게요! :)

(출처 : https://school.programmers.co.kr/learn/courses/30/lessons/131124)


 

1. 문제 :  그룹별 조건에 맞는 식당 목록 출력하기(Lv. 4)

 

 

 


 

2. 문제 설명

다음은 고객의 정보를 담은 MEMBER_PROFILE 테이블과

식당의 리뷰 정보를 담은 REST_REVIEW 테이블입니다.

 

MEMBER_PROFILE 테이블은 다음과 같으며

MEMBER_ID, MEMBER_NAME, TLNO, GENDER, DATE_OF_BIRTH는

회원 ID, 회원 이름, 회원 연락처, 성별, 생년월일을 의미합니다.

 

[ 테이블 구조('MEMBER_PROFILE') ]

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, 점수, 리뷰 텍스트, 리뷰 작성일을 의미합니다.

 

[ 테이블 구조('REST_REVIEW') ]

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의 데이트 포맷이 예시와 동일해야 정답처리 됩니다.


 

3. 문제 풀이

-- 1안
WITH RM AS (
    SELECT  MEMBER_ID
            , COUNT(MEMBER_ID) AS CNT
      FROM  REST_REVIEW
     GROUP
        BY  MEMBER_ID
     ORDER
        BY CNT DESC
     LIMIT 1
)
SELECT  MP.MEMBER_NAME AS MEMBER_NAME,
        RR.REVIEW_TEXT AS REVIEW_TEXT,
        DATE_FORMAT(RR.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
  FROM  MEMBER_PROFILE AS MP
 INNER
  JOIN  REST_REVIEW AS RR
    ON  MP.MEMBER_ID = RR.MEMBER_ID
 INNER
  JOIN  RM
    ON  RR.MEMBER_ID = RM.MEMBER_ID
 ORDER
    BY  REVIEW_DATE ASC
        , REVIEW_TEXT ASC

 

 

이번 문제는 WITH문을 이용해서  한 가지 풀이로 작성했습니다!

 

#  1안 풀이 설명

# [ 문제 접근 설명 ]


문제를 읽고 조건에 맞는 쿼리를 작성하기 위해서 다음과 같이  네 가지 단계로 진행했어요!

1. WITH문과 LIMIT를 이용하여 가장 많이 리뷰를 작성한 작성자를 산출(WITH 문)
2. MEMBER_PROFILE 테이블을  MEMBER_ID 기준으로 REST_REVIEW 테이블과 조인하기(INNER JOIN)
3. MEMBER_PROFILE 테이블을  MEMBER_ID 기준으로 WITH문으로 생성한 RM 테이블과 조인하기(INNER JOIN)
4. 컬럼 선택 및 리뷰 작성일 포맷변경(SELECT)
5. 리뷰 작성일, 리뷰텍스트 기준으로 오름차순 정렬(ORDER BY)

 

# [ 1안 쿼리 작성 설명 ]

 

 1  첫 번째 단계에서는 WITH문을 이용했습니다!

 

REST_REVIRE테이블에서 리뮤를 가장 많이 작성한 고객의 ID와 횟수를 산출하고 이를 정렬을 했습니다.

 

이후 LIMIT 1을 이용해서 한 명의 고객만을 나타내었어요!

 

이렇게 만든 결과 값은 RM이라는 이름으로 저장하였습니다.

 


WITH RM AS (
    SELECT  MEMBER_ID
                     , COUNT(MEMBER_ID) AS CNT
        FROM   REST_REVIEW
     GROUP
             BY  MEMBER_ID
     ORDER
             BY  CNT DESC
         LIMIT  1
)

 

 2  두 번째 단계에서는 테이블을 조인했습니다!

 

MEMBER_PROFILE 테이블을  MEMBER_ID 기준으로 REST_REVIEW 테이블과  INNER JOIN 했어요!

 

두 테이블이 공통으로 가지고 있는 컬럼인 MEMBER_ID를 이용해서 ON 조건을 써주었습니다.

 


WITH RM AS (
    SELECT  MEMBER_ID
                     , COUNT(MEMBER_ID) AS CNT
        FROM   REST_REVIEW
     GROUP
             BY  MEMBER_ID
     ORDER
             BY  CNT DESC
         LIMIT  1
)

SELECT   *
   FROM   MEMBER_PROFILE AS MP
  INNER
     JOIN   REST_REVIEW AS RR
        ON   MP.MEMBER_ID = RR.MEMBER_ID

 

 3  세 번째 단계에서는 두 번째 단계와 동일하게 테이블을 조인했습니다!

 

MEMBER_PROFILE 테이블을  MEMBER_ID 기준으로 RM 테이블과  INNER JOIN 했어요!

 

두 테이블이 공통으로 가지고 있는 컬럼인 MEMBER_ID를 이용해서 ON 조건을 써주었습니다.

 


WITH RM AS (
    SELECT  MEMBER_ID
                     , COUNT(MEMBER_ID) AS CNT
        FROM   REST_REVIEW
     GROUP
             BY  MEMBER_ID
     ORDER
             BY  CNT DESC
         LIMIT  1
)

SELECT   *
   FROM   MEMBER_PROFILE AS MP
  INNER
     JOIN   REST_REVIEW AS RR
        ON   MP.MEMBER_ID = RR.MEMBER_ID
  INNER
     JOIN   RM
        ON   MP.MEMBER_ID = RM.MEMBER_ID

 

 4  네 번째 단계에서는 출력할 컬럼과 날짜 포맷을 변경해 주었어요!

 

MEMBER_PROFILE 테이블을  MEMBER_ID 기준으로 RM 테이블과  INNER JOIN 했어요!

 

두 테이블이 공통으로 가지고 있는 컬럼인 MEMBER_ID를 이용해서 ON 조건을 써주었습니다.

 


WITH RM AS (
    SELECT  MEMBER_ID
                     , COUNT(MEMBER_ID) AS CNT
        FROM   REST_REVIEW
     GROUP
             BY  MEMBER_ID
     ORDER
             BY  CNT DESC
         LIMIT  1
)

SELECT  MP.MEMBER_NAME AS MEMBER_NAME
                 , RR.REVIEW_TEXT AS REVIEW_TEXT
                 , DATE_FORMAT(RR.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
   FROM   MEMBER_PROFILE AS MP
  INNER
     JOIN   REST_REVIEW AS RR
        ON   MP.MEMBER_ID = RR.MEMBER_ID
  INNER
     JOIN   RM
        ON   MP.MEMBER_ID = RM.MEMBER_ID

 

 

 5  마지막으로는 요구사항에 맞게 정렬했어요!

리뷰 작성일(REVIEW_DATE) 기준 오름차순 정별,

 

그리고 리뷰 텍스트(REVIEW_TEXT) 기준 오름차순으로 정렬했습니다!

 


WITH RM AS (
    SELECT  MEMBER_ID
                     , COUNT(MEMBER_ID) AS CNT
        FROM   REST_REVIEW
     GROUP
             BY  MEMBER_ID
     ORDER
             BY  CNT DESC
         LIMIT  1
)
SELECT  MP.MEMBER_NAME AS MEMBER_NAME
                 , RR.REVIEW_TEXT AS REVIEW_TEXT
                 , DATE_FORMAT(RR.REVIEW_DATE, '%Y-%m-%d') AS REVIEW_DATE
   FROM   MEMBER_PROFILE AS MP
  INNER
     JOIN   REST_REVIEW AS RR
        ON   MP.MEMBER_ID = RR.MEMBER_ID
  INNER
     JOIN   RM
        ON   MP.MEMBER_ID = RM.MEMBER_ID
 ORDER
          BY  REVIEW_DATE ASC
                 , REVIEW_TEXT ASC

 

 

정답...!


 

4. 데코의 문제 풀이 후기

이번 문제는 LEVEL 4인 문제였는데요, 제가 다룬 글에서 처음으로 WITH문을 이용했습니다!

 

사실 서브쿼리로도 동일한 내용을 수행할 수 있는데, 

 

WITH문을 소개해드릴 겸 WITH문을 이용해서 작성해보았습니다.

 

WITH문 이후에는 테이블을 JOIN 하고 ORDER BY 하면 되는 기존에 다 다룬 문제입니다!

 

이외에 따로 코멘트할 것은 없네요!

혹시나 더 좋은 쿼리나 어렵게 느껴지신 부분이 있다면 댓글로 남겨주세요! 

 



이번 문제는 WITH문으로 테이블을 생성하고 테이블을 결합하여 추출하는 쿼리를 작성해 보았습니다!

설명이 어려운 부분 혹은 잘 이해가 안 가는 부분

그리고 더 궁금한 내용이 있다면

언제든지 댓글로 남겨주세요!

빠르게 궁금증을 해결해 드릴게요!

공감과 댓글은 큰 힘이 됩니다!

오늘도 블로그 방문해 주시고

포스팅 읽어주셔서 감사합니다!

 

 

LIST