| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- date_format
- ifnull
- 해외결제
- SubQuery
- MAX
- 날짜 포맷
- MySQL
- order by
- programmers
- Python
- join
- is null
- having
- 투자자산운용사
- Round
- IELTS
- 도서추천
- inner join
- 서브쿼리
- GROUP BY
- count
- where
- alias
- 금융IT
- IN
- SQL
- LIMIT
- IS NOT NULL
- 금융 플랫폼
- 트래블테크
- Today
- Total
Every Step Matters
[프로그래머스 SQL Lv.4] 서울에 위치한 식당 목록 출력하기 (MySQL) 본문
문제링크 : 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'Database > SQL' 카테고리의 다른 글
| [프로그래머스 SQL Lv.2] 3월에 태어난 여성 회원 목록 출력하기 (MySQL) (0) | 2026.01.07 |
|---|---|
| [SQL] 서브 쿼리 (SubQuery) : (4) 스칼라 서브 쿼리 (단 하나의 값만 반환, SELECT절에 작성) (0) | 2026.01.07 |
| [SQL] 서브 쿼리 (SubQuery) : (3) 인라인 뷰 (FROM절에 작성) (0) | 2026.01.07 |
| [SQL] 서브 쿼리 (SubQuery) : (2) 중첩 서브 쿼리 (WHERE절에 작성) (0) | 2026.01.06 |
| [프로그래머스 SQL Lv.3] 업그레이드 할 수 없는 아이템 구하기 (MySQL) (0) | 2026.01.05 |