[SQL] 131123 즐겨찾기가 가장 많은 식당 정보 출력하기
https://school.programmers.co.kr/learn/courses/30/lessons/131123
📌문제
- 테이블 : REST_INFO
- 조건
- 음식 종류별로 즐겨찾기가 가장 많은 식당의
- 음식 종류, ID, 식당이름, 즐겨찾기 수
- 정렬
- 음식 종류 기준 내림차순
💡 정답쿼리
CTE + ROW_NUMBER() + PARTITION BY
이건 윈도우 함수 써서 푼 방식이다. 전체 테이블 스캔 후에 FOOD_TYPE 별로 그룹을 나누고, 각 그룹 안에서 FAVORITES 내림차순 정렬한다. 순위 계산 후 rn = 1 필터링한다. 이렇게 하면 가독성이 좋다.
WITH ranked_rest AS (
SELECT rest_id,
rest_name,
food_type,
favorites,
ROW_NUMBER() OVER (PARTITION BY food_type ORDER BY favorites DESC) AS rn
FROM rest_info
)
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM ranked_rest
WHERE rn = 1
ORDER BY food_type DESC;
- ROW_NUMBER() + PARTITION BY FOOD_TYPE
→ 음식 종류별로 순위 매기기 - ORDER BY FAVORITES DESC
→ 즐겨찾기 수가 높은 순으로 정렬해서 1위만 가져오기 - 마지막에 WHERE rn = 1로 각 음식 종류의 최상위 식당만 필터링,
- 결과는 ORDER BY FOOD_TYPE DESC 로 음식 종류 기준 내림차순
하지만 MySQL은 윈도 함수 계산시 내부적으로 정렬이 필요하므로 큰 데이터에서 메모리랑 정렬 비용이 크다.
GROUP BY + MAX()
SELECT r.FOOD_TYPE, r.REST_ID, r.REST_NAME, r.FAVORITES
FROM REST_INFO r
JOIN (
SELECT FOOD_TYPE, MAX(FAVORITES) AS max_fav
FROM REST_INFO
GROUP BY FOOD_TYPE
) m ON r.FOOD_TYPE = m.FOOD_TYPE AND r.FAVORITES = m.max_fav
ORDER BY r.FOOD_TYPE DESC;
- GROUP BY로 각 음식 종류별 최대 즐겨찾기 수 계산하기
- 원본 테이블과 조인해서 해당 최대값을 가진 레코드 가져오기
이렇게 하면 보통 윈도우 함수보다 메모리 사용량이 적다.
결론
- 데이터가 수십만 건 이상이고 단순히 "그룹별 최댓값"만 구한다면 GROUP BY + MAX() 방식이 더 빠르다.
- 하지만 앞으로 "그룹별 상위 N개" 같은 요구가 생길 수 있다면 처음부터 ROW_NUMBER()을 쓰는게 유지보수에 좋다.