Every Step Matters

[프로그래머스 SQL Lv.4] 서울에 위치한 식당 목록 출력하기 (MySQL) 본문

Database/SQL

[프로그래머스 SQL Lv.4] 서울에 위치한 식당 목록 출력하기 (MySQL)

imnyoung 2026. 1. 7. 16:49

문제링크 : https://school.programmers.co.kr/learn/courses/30/lessons/131118

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

1. 테이블

(1) REST_INFO

Column name Type Nullable Description
REST_ID VARCHAR(5) FALSE 식당 ID
REST_NAME VARCHAR(50) FALSE 식당 이름
FOOD_TYPE VARCHAR(20) TRUE 음식 종류
VIEWS NUMBER TRUE 조회수
FAVORITES NUMBER TRUE 즐겨찾기수
PARKING_LOT VARCHAR(1) TRUE 주차장 유무
ADDRESS VARCHAR(100) TRUE 주소
TEL VARCHAR(100) TRUE 전화번호

(2) REST_REVIEW

Column name Type Nullable Description
REVIEW_ID VARCHAR(10) FALSE 리뷰 ID
REST_ID VARCHAR(10) TRUE 식당 ID
MEMBER_ID VARCHAR(100) TRUE 회원 ID
REVIEW_SCORE NUMBER TRUE 점수
REVIEW_TEXT VARCHAR(1000) TRUE 리뷰 텍스트
REVIEW_DATE DATE TRUE 리뷰 작성일

 

2. 문제

REST_INFO와 REST_REVIEW 테이블에서 (1) 서울에 위치한 식당들의 (2) 식당 ID, 식당 이름, 음식 종류, 즐겨찾기수, 주소, 리뷰 평균 점수를 조회하는 SQL문을 작성해주세요. 이때 (3) 리뷰 평균점수는 소수점 세 번째 자리에서 반올림 해주시고 (4) 결과는 평균점수를 기준으로 내림차순 정렬해주시고, (5) 평균점수가 같다면 즐겨찾기수를 기준으로 내림차순 정렬해주세요.

 

3. 문제풀이

문제 풀이를 위한 나의 의식의 흐름은 다음과 같았다.

1) 서울에 위치한 식당을 필터링해야 한다.

2) 식당별로 리뷰 평균점수를 구해야 하므로 GROUP BY를 이용해야 한다.

3) GROUP BY를 메인 쿼리에서 사용하려면 식당 ID, 식당 이름, 음식 종류 등이 모두 그룹화 기준이 되어야 한다.(GROUP BY 원칙에 의해!) 메인 쿼리의 SELECT 문에 이용할 수 없으므로 서브쿼리를 활용하여 미리 GROUP BY한 결과를 조인에 활용하자.

[GROUP BY 원칙]
SELECT 절에 집계 함수와 함께 사용되지 않은 컬럼은
반드시 GROUP BY 절에 포함되어야 한다.

 

따라서 먼저 GROUP BY를 활용하여 식당별 리뷰 평균점수를 출력하는 인라인 뷰를 만든다.

SELECT rest_id, ROUND(AVG(review_score),2) AS score   -- 식당 ID와 식당별 리뷰 평균점수 조회.
FROM rest_review 
GROUP BY rest_id
(3) 리뷰 평균점수는 소수점 세 번째 자리에서 반올림한다.

쿼리 실행 결과

 

다음으로 이 테이블을 REST_INFO 테이블과 조인하고, 필요한 컬럼을 SELECT절에 작성한다.

-- (2) 식당 ID, 식당 이름, 음식 종류, 즐겨찾기수, 주소, 리뷰 평균 점수를 조회
SELECT T1.rest_id, rest_name, food_type, favorites, address, score  
FROM rest_info T1
JOIN (
    SELECT rest_id, ROUND(AVG(review_score),2) AS score 
    FROM rest_review 
    GROUP BY rest_id) T2
ON T1.rest_id = T2.rest_id

이제 조인한 테이블에서 WHERE을 사용하여 (1) 서울에 위치한 식당 만을 필터링한다.

SELECT T1.rest_id, rest_name, food_type, favorites, address, score
FROM rest_info T1
JOIN (
    SELECT rest_id, ROUND(AVG(review_score),2) AS score 
    FROM rest_review 
    GROUP BY rest_id) T2
ON T1.rest_id = T2.rest_id
WHERE address LIKE '서울%'  -- 주소 처음이 '서울'로 시작하는 경우만 필터링

마지막으로 정렬 조건에 맞게 정렬한다.

SELECT T1.rest_id, rest_name, food_type, favorites, address, score
FROM rest_info T1
JOIN (
    SELECT rest_id, ROUND(AVG(review_score),2) AS score 
    FROM rest_review 
    GROUP BY rest_id) T2
ON T1.rest_id = T2.rest_id
WHERE address LIKE '서울%'
ORDER BY score DESC, favorites DESC -- (4) 평균점수를 기준으로 내림차순 정렬, (5) 평균점수가 같다면 즐겨찾기수를 기준으로 내림차순 정렬

 

4. 정답

따라서 정답은

SELECT T1.rest_id, rest_name, food_type, favorites, address, score
FROM rest_info T1
JOIN (
    SELECT rest_id, ROUND(AVG(review_score),2) AS score 
    FROM rest_review 
    GROUP BY rest_id) T2
ON T1.rest_id = T2.rest_id
WHERE address LIKE '서울%'
ORDER BY score DESC, favorites DESC