문제

코딩테스트 연습 - 즐겨찾기가 가장 많은 식당 정보 출력하기

오답

SELECT FOOD_TYPE, REST_ID, REST_NAME, MAX(FAVORITES)
FROM REST_INFO
GROUP BY FOOD_TYPE
ORDER BY FOOD_TYPE DESC;

위 코드는 MAX(FAVORITES)를 제외한 SELECT FOOD_TYPE, REST_ID, REST_NAME의 경우 문제에서 요구하는 즐겨찾기 수가 가장 많은 식당의 정보가 아닌 테이블에서 임의의 순서로 정렬된 식당 정보 중 가장 상단의 식당 정보를 가져온다. 다음 코드를 실행해보면 다른 FOOD_TYPE은 우연히 테이블 상당의 식당 정보가 즐겨찾기 수가 가장 많은 식당이지만 일식 REST_ID=00002는 아니다. 하이가쯔네는 테이블 가장 상단의 식당 정보로 이 식당의 FAVORITES(112)과 MAX(FAVORITES)(230)가 다름을 확인할 수 있다. 문제의 요구사항을 맞추려면 MAX(FAVORITES)를 기준으로 해당 값을 가진 식당의 정보를 찾아 출력해야 한다.

정답

SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM REST_INFO
WHERE (FOOD_TYPE, FAVORITES) 
IN (SELECT FOOD_TYPE, MAX(FAVORITES)
FROM REST_INFO
GROUP BY FOOD_TYPE)
ORDER BY FOOD_TYPE DESC

해설

SELECT의 쿼리 실행 순서는 다음과 같다.

 SELECT SQL query execution order

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY
  7. LIMIT

다음 명령어의 실행 순서를 정리해보면 먼저 1번 FROM, 3번 GROUP BY, 5번 SELECT 순으로 실행된다. 실행 결과 마지막에 실행되는 SELECT 명령어가 그룹화된 테이블 가장 상단에 있는 데이터를 임의로 가져오는 걸 확인할 수 있다.

select food_type, rest_id, rest_name, favorites from rest_info
group by food_type

임의의 순서는 GROUP BY 없이 SELECT 만 실행해보면 알 수 있다. 다음과 같이 ‘REST_ID’ 를 기준으로 오름차순 정렬한 결과가 나온다.

select food_type, rest_id, rest_name, favorites from rest_info

정답인 코드의 순서를 확인해보자. 먼저 서브 쿼리에서 3번 GROUP BY 명령어 실행 후 각 food_type과 favorites의 max 값을 찾아준다.

select food_type, max(favorites) from rest_info
group by food_type

이 서브 쿼리의 결과값을 기준으로 메인 쿼리가 다음 순서로 실행된다.

  1. from: rest_info 테이블에서 데이터를 찾는다
  2. where: 서브쿼리 결과값과 일치하는 데이터를 찾는다.
  3. select: 해당 데이터에서 ‘food_type, rest_id, rest_name, favorites’ 항목을 출력한다. 2번 과정에서 in 구문으로 인해 서브 쿼리 값에 있는 식당 중 출력에 필요한 정보를 가져온다
    select food_type, rest_id, rest_name, favorites from rest_info
    where (food_type, favorites)
    in (select food_type, max(favorites) from rest_info
    group by food_type)
    

여기에 마지막으로 6번 ORDER BY 명령어를 실행해주면 출력된 결과값을 ‘food_type’을 기준으로 내림차순 정렬해준다.

select food_type, rest_id, rest_name, favorites from rest_info
where (food_type, favorites)
in (select food_type, max(favorites) from rest_info
group by food_type)
order by food_type desc

비슷한 문제

  • 같은 풀이 방식이 필요한 문제
    • https://school.programmers.co.kr/learn/courses/30/lessons/131116
  • GROUP BY, MAX를 사용하지만 다른 풀이 방식이 필요한 문제
    • https://school.programmers.co.kr/learn/courses/30/lessons/298519

참고자료

댓글남기기