https://school.programmers.co.kr/learn/courses/30/lessons/131123
SELECT FOOD_TYPE, REST_ID, REST_NAME, MAX(FAVORITES) FAVORITES
FROM REST_INFO
GROUP BY FOOD_TYPE
ORDER BY FOOD_TYPE DESC;
쿼리를 이렇게 작성했는데 FOOD_TYPE 카테고리 별로 MAX값이 잘 나오지 않은 것.
뭐가 문제인가 찾아보니 GROUP BY 절의 동작 방식의 이해가 부족했다
GROUP BY를 사용하면 그룹 별로 가장 상단에 있는 데이터들을 임의로 가져온다.
+-----------+---------+-------------+-----------+
| FOOD_TYPE | REST_ID | REST_NAME | FAVORITES |
+-----------+---------+-------------+-----------+
| 일식 | 00002 | 하이가쯔네 | 112 |
| 일식 | 00023 | 싹쓰리 | 42 |
| 일식 | 00005 | 코슌스 | 123 |
| 일식 | 00004 | 스시사카우스 | 230 |
+-----------+---------+-------------+-----------+
예를 들어, FOOD_TYPE이 일식인 데이터들이 위와 같을 때, 내가 작성했던 쿼리를 적용한다면
+-----------+---------+-------------+-----------+
| FOOD_TYPE | REST_ID | REST_NAME | FAVORITES |
+-----------+---------+-------------+-----------+
| 일식 | 00002 | 하이가쯔네 | 230 |
| 일식 | 00023 | 싹쓰리 | 230 |
| 일식 | 00005 | 코슌스 | 230 |
| 일식 | 00004 | 스시사카우스 | 230 |
+-----------+---------+-------------+-----------+
SQL 내부적으로 이렇게 FAVORITES를 전체적으로 MAX값으로 적용하여 맨 위에 있는 컬럼을 가져오게 된다.
따라서 FAVORITES은 원하는 값이 맞고 FOOD_TYPE도 그룹화하여 전부 동일하므로 문제가 없지만, REST_ID, REST_NAME 은 다른 데이터의 값으로 나오게 되는 것이다.
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM REST_INFO
GROUP BY FOOD_TYPE
HAVING FAVORITES = MAX(FAVORITES)
ORDER BY FOOD_TYPE DESC;
이 SQL문을 실행하면 문제가 되는 일식 카테고리 자체가 출력이 되지 않는데,
GROUP BY로 카테고리별 맨 첫번째 데이터들을 가져온 후에 HAVING이 실행되기 때문에
가져온 맨 첫번째 데이터가 일식 카테고리의 MAX값이 아니라 출력이 되지 않은 것 같다.
# 1
SELECT A.FOOD_TYPE, A.REST_ID, A.REST_NAME, A.FAVORITES
FROM REST_INFO A, (SELECT MAX(FAVORITES) MAX
FROM REST_INFO
GROUP BY FOOD_TYPE) B
WHERE A.FAVORITES = B.MAX
GROUP BY FOOD_TYPE
ORDER BY FOOD_TYPE DESC;
# 2
SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM REST_INFO
WHERE FAVORITES IN (SELECT MAX(FAVORITES)
FROM REST_INFO
GROUP BY FOOD_TYPE)
GROUP BY FOOD_TYPE
ORDER BY FOOD_TYPE DESC;
이를 해결하기 위해 서브쿼리를 사용하여
1. B 테이블에 FOOD_TYPE 별로 FAVORITES의 MAX값들을 가져와서
2. A 테이블에서 FAVORITES로 해당 MAX값을 가진 데이터를 가져오고
3. FOOD_TYPE 별로 그룹화하여 정렬한 후 출력해주었다
(1, 2번 둘 다 같은 로직이다)