프로그래머스에서 제공하는 SQL문제 매일 풀기 챌린지
문제 설명
다음은 식당의 정보를 담은 REST_INFO 테이블입니다. REST_INFO 테이블은 다음과 같으며 REST_ID, REST_NAME, FOOD_TYPE, VIEWS, FAVORITES, PARKING_LOT, ADDRESS, TEL은 식당 ID, 식당 이름, 음식 종류, 조회수, 즐겨찾기수, 주차장 유무, 주소, 전화번호를 의미합니다
Column name | Type | Nullable |
REST_ID | VARCHAR(5) | FALSE |
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 |
문제
REST_INFO 테이블에서 음식종류별로 즐겨찾기수가 가장 많은 식당의 음식 종류, ID, 식당 이름, 즐겨찾기수를 조회하는 SQL문을 작성해주세요. 이때 결과는 음식 종류를 기준으로 내림차순 정렬해주세요.
예시
REST_INFO 테이블이 다음과 같을 때
REST_ID | REST_NAME | FOOD_TYPE | VIEWS | FAVORITE | SPARKING_LOT | ADDRESS | TEL |
00001 | 은돼지식당 | 한식 | 1150345 | 734 | N | 서울특별시 중구 다산로 149 | 010-4484-8751 |
00002 | 하이가쯔네 | 일식 | 120034 | 112 | N | 서울시 중구 신당동 375-21 | NULL |
00003 | 따띠따띠뜨 | 양식 | 1234023 | 102 | N | 서울시 강남구 신사동 627-3 1F | 02-6397-1023 |
00004 | 스시사카우스 | 일식 | 1522074 | 230 | N | 서울시 서울시 강남구 신사동 627-27 | 010-9394-2554 |
00005 | 코슌스 | 일식 | 15301 | 123 | N | 서울특별시 강남구 언주로153길 | 010-1315-8729 |
SQL을 실행하면 다음과 같이 출력되어야 합니다
FOOD_TYPE | REST_ID | REST_NAME | FAVORITES |
한식 | 00001 | 은돼지식당 | 734 |
일식 | 00004 | 스시사카우스 | 230 |
양식 | 00003 | 따띠따띠뜨 | 102 |
♥ 오라클 정답
select food_type, rest_id, rest_name, favorites
from (select food_type, rest_id, rest_name,favorites,
rank() over (partition by food_type order by favorites desc) rnk
from rest_info)
where rnk = 1
order by food_type desc;
♥ MySQL 정답
select food_type, rest_id, rest_name, favorites
from (select food_type, rest_id, rest_name,favorites,
rank() over (partition by food_type order by favorites desc) rnk
from rest_info) dd
where rnk = 1
order by food_type desc;
해설해보기
인라인뷰( from절의 서브쿼리 )를 사용하여 food_type별 순위를 출력하고
그 결과를 가지고 메인쿼리에서 조건을 주어 food_type별 즐겨찾기 수가 가장 많은 식당에 대한 정보를 출력할 수 있다.
■ IN LINE VIEW
ORACLE과 MySQL의 차이점은
MySQL에서는 IN LINE VIEW에 별칭을 지정해줘야 오류가 발생하지 않는 것이다.
ORACLE은 별칭이 없어도 에러가 발생하지 않았다.
# 1. SELECT절
출력해야할 컬럼명들을 나열해주고, 마지막에 순위를 구하기 위해서 RANK() 윈도우함수를 사용해준다.
FOOD_TYPE 별 순위를 구해야하기 때문에 PARTITION 을 FOOD_TYPE별로 나누어주고,
즐겨찾기 수가 많은 것이 순위가 높기 때문에 FAVORITES 컬럼을 기준을 DESC하게 정렬해준다.
마지막으로 메인쿼리에서 사용하기 위해서 별칭을 지정해준다.
rank() over (partition by food_type order by favorites desc) rnk
● 윈도우 함수(WINDOW FUNCTION)
윈도우 함수는 특정 창(Window) 또는 그룹 내에서 데이터를 처리하고 계산하는 데 사용된다.
일반적으로 집계 함수와는 달리 개별 행에 대한 계산을 수행하며
데이터 집합을 여러 그룹으로 나눌 필요 없이 전체 데이터 집합에 대해 작동한다.
윈도우 함수는 OVER절을 사용하여 정의하고, 윈도우의 파티션(분할 기준), 정렬 순서(ORDER BY), 윈도우 프레임(계산 대상 행의 범위) 등을 지정할 수 있다.
주로 아래와 같은 상황에서 사용한다.
- 순위를 계산하는 함수 : RANK(), DENSE_RANK(), ROW_NUMBER() 등
- 누적 합, 평균, 최소값, 최대값 계산: `SUM()`, `AVG()`, `MIN()`, `MAX()` 등
# 2. FROM절
데이터를 가져올 테이블 명을 입력해준다.
■ MAIN QUERY
# 1. SELECT절
출력해야할 컬럼명들을 나열해준다.
# 2. FROM절
IN LINE VIEW(FOM절의 서브쿼리)를 작성해준다.
# 3. WHERE절
IN LINE VIEW에서 출력된 순위를 가지고
순위가 1등인 데이터만 출력할 수 있게 조건을 준다.
# 4. ORDER BY
FOOD_TYPE 을 기준으로 DESC하게 정렬해준다.
출처 : 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
'SQL 문제 풀기 > 1. 프로그래머스 SQL : 2023.12.17~2024.2.29' 카테고리의 다른 글
<프로그래머스 57> 조건에 맞는 사용자 정보 조회하기(Lv.3) (2) | 2024.02.11 |
---|---|
<프로그래머스 56> 없어진 기록 찾기(Lv.3) (2) | 2024.02.10 |
<프로그래머스 54>대여 기록이 존재하는 자동차 리스트 구하기(Lv.3) (2) | 2024.02.08 |
<프로그래머스 53> 조건에 맞는 사용자와 총 거래금액 조회하기(Lv.3) (4) | 2024.02.07 |
<프로그래머스 52> 오랜 기간 보호한 동물(2)(Lv.3) (2) | 2024.02.06 |