안녕하세요! 데코입니다!
오늘은 프로그래머스 코딩테스트 연습에 있는 "그룹별 조건에 맞는 식당 목록 출력하기" 문제를 포스팅하려고 합니다!
바로 포스팅 시작할게요! :)
(출처 : 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문으로 테이블을 생성하고 테이블을 결합하여 추출하는 쿼리를 작성해 보았습니다!
설명이 어려운 부분 혹은 잘 이해가 안 가는 부분
그리고 더 궁금한 내용이 있다면
언제든지 댓글로 남겨주세요!
빠르게 궁금증을 해결해 드릴게요!
공감과 댓글은 큰 힘이 됩니다!
오늘도 블로그 방문해 주시고
포스팅 읽어주셔서 감사합니다!
'Skill Sets > SQL' 카테고리의 다른 글
[SQL] 조건별로 분류하여 주문상태 출력하기(프로그래머스/MySQL/Level 3) (59) | 2024.02.03 |
---|---|
[SQL] 5월 식품들의 총매출 조회하기(프로그래머스/MySQL/Level 4) (51) | 2024.01.29 |
[SQL] 상품을 구매한 회원 비율 구하기(프로그래머스/MySQL/Level 5) (81) | 2023.12.01 |
[SQL] 즐겨찾기가 가장 많은 식당 정보 출력하기(프로그래머스/MySQL/Level 3) (53) | 2023.11.19 |
[SQL] 오프라인/온라인 판매 데이터 통합하기(프로그래머스/MySQL/Level 4) (69) | 2023.11.11 |