Study/SQL

[프로그래머스 SQL] 즐겨찾기가 가장 많은 식당 정보 출력하기

delay100 2024. 1. 16. 15:04
728x90
반응형
SMALL

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

난이도: Lv.3 

언어: MySQL

https://school.programmers.co.kr/learn/courses/30/lessons/131123

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

실패

실패1.

SELECT a.FOOD_TYPE, a.REST_ID, a.REST_NAME, a.FAVORITES
FROM REST_INFO a
GROUP BY a.FOOD_TYPE
HAVING MAX(a.FAVORITES) = a.FAVORITES
ORDER BY a.FOOD_TYPE DESC

실패이유1. GROUP BY를 하면 가장 위에 있는 행을 기준으로 그룹화 됨.

SELECT * FROM REST_INFO 결과

REST_INFO 테이블을 SELECT해보면 위의 테이블이 나옵니다.

FOOD_TYPE을 기준으로 GROUP BY를 하면 가장 위에있는 한식 - 은돼지식당, 일식 - 하이가쯔네, 양식 - 따띠따띠뜨, 분식 - 애플우스 행을 기준으로 그룹화가 됩니다.

HAVING에 대해 오해가 있었는데, GROUP을 하기 전에 GROUP에 대한 조건을 적는 것으로 알고 있었습니다.

HAVING은 GROUP화가 된 이후의 값(그룹화한 항목에 대해)에 대한 처리를 적어주는 것입니다.

즉, GROUP BY가 일어나기 전에 FAVORITES를 정렬해야함!

실패2.

SELECT a.FOOD_TYPE, a.REST_ID, a.REST_NAME, a.FAVORITES
FROM REST_INFO a
WHERE a.FAVORITES IN (
    SELECT b.FAVORITES
    FROM REST_INFO b
    ORDER BY b.FAVORITES DESC
)
GROUP BY a.FOOD_TYPE
HAVING MAX(a.FAVORITES) = a.FAVORITES
ORDER BY a.FOOD_TYPE DESC

실패이유1. 실패1의 실패이유와 동일(GROUP BY를 하면 가장 위에 있는 행을 기준으로 그룹화 됨)

실패이유2. 가장 큰 값에 대한 조건이 없음.

실패이유1때문에 가장 큰 값에 대한 조건이 명시되어있지 않고 있습니다.

이 문제를 해결하는데 있어서 많은 힌트를 보았기 때문에 또한번 꼭 풀어봐야겠습니다..

 

성공

# 정답쿼리
SELECT a.FOOD_TYPE, a.REST_ID, a.REST_NAME, a.FAVORITES
FROM REST_INFO a
    JOIN (
        SELECT b.FOOD_TYPE, MAX(b.FAVORITES) AS FAVORITES
        FROM REST_INFO b
        GROUP BY b.FOOD_TYPE
    ) c ON a.FOOD_TYPE = c.FOOD_TYPE AND a.FAVORITES = c.FAVORITES
ORDER BY a.FOOD_TYPE DESC

FROM 절에서 자기 자신에 대해 JOIN을 함으로써 필요한 행을 걸러내는 작업을 합니다.

FOOD_TYPE에 대해 그룹을 묶고 그 결과에 대해 SELECT문에서 MAX값인 행을 뽑아냈습니다.

 

내부 쿼리를 실행하면 아래와 같습니다.

# 내부쿼리
SELECT b.FOOD_TYPE, MAX(b.FAVORITES) AS FAVORITES
FROM REST_INFO b
GROUP BY b.FOOD_TYPE

내부 쿼리 결과값

이렇게 하면 의문이 생기는데..

내부 쿼리에서 FOOD_TYPE, FAVORITES를 다 가져오게 되네?

그냥 내부 쿼리에서 다 하면 되는거 아닌가?

라는 생각이 들게 됩니다 ..(저는 의문이 들었어요..)

따라서 아래와 같이 쿼리를 다시 해보았고..

하지만!!

# 내부쿼리 수정
SELECT b.FOOD_TYPE, b.REST_ID, b.REST_NAME, MAX(b.FAVORITES) AS FAVORITES
FROM REST_INFO b
GROUP BY b.FOOD_TYPE

내부 쿼리 수정 결과값

쿼리를 이렇게 만들어버리면 REST_ID, REST_NAME은 GROUP BY에 의해서 가장 위에 있는 REST_ID, REST_NAME이 들어가버려서 데이터가 맞지 않게 됩니다.

결국 REST_ID, REST_NAME 때문에 JOIN이 필요하다는 것을 납득하게됩니다 ...

 

*참고 chatGPT

없습니다.


코드에 질문이 있으시면 댓글을 달아주세요. 최대한 빠른 시일 내에 답변해드리겠습니다. 

봐주셔서 감사합니다.

728x90
반응형
LIST