https://school.programmers.co.kr/learn/courses/30/lessons/131123
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
위 문제를 풀면서 깨달은 GROUP BY의 올바른 사용법에 대해 기록한다.
처음에는 다음과 같이 SQL문을 작성하여 틀렸다.
SQL:
SELECT FOOD_TYPE, REST_ID, REST_NAME, MAX(FAVORITES) AS FAVORITES
FROM REST_INFO
GROUP BY FOOD_TYPE
ORDER BY FOOD_TYPE DESC
결과 :
우선 REST_ID, REST_NAME은 집계 함수로 표현되지 않아 여러 행이 될 수 있는 값들이다.
한편, FOOD_TYPE은 GROUP BY 절에 명시되어 있고, FAVORITES는 MAX 함수로 한 개의 값으로 특정된다.
많은 경우에 이와 같은 쿼리는 오류를 일으키고 실행되지 않는다. 예를 들어, 오라클의 경우 ORA-00937 오류를 뱉고 쿼리가 실행이 안된다.
MySQL의 경우 버전 및 서버 설정에 따라 위와 같은 쿼리가 실행 된다. 이에 대해서는 아래의 공식 문서에 잘 설명되어 있다.
https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html
MySQL :: MySQL 8.0 Reference Manual :: 14.19.3 MySQL Handling of GROUP BY
14.19.3 MySQL Handling of GROUP BY SQL-92 and earlier does not permit queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are not named in the GROUP BY clause. For example, this query is illegal in sta
dev.mysql.com
결론적으로, REST_ID와 REST_NAME은 FOOD_TYPE으로 묶여진 그룹들 중에서 그냥 아무 값이나 출력된 것이다. 따라서 이 값들도 FAVORITES값이 가장 큰 행의 값들로 출력되도록 다음과 같이 작성해야 옳다.
SELECT R1.FOOD_TYPE, R1.REST_ID, R1.REST_NAME, R1.FAVORITES
FROM REST_INFO R1
JOIN (SELECT FOOD_TYPE, MAX(FAVORITES) AS MAX_FAVORITES FROM REST_INFO GROUP BY FOOD_TYPE) R2
ON R1.FOOD_TYPE = R2.FOOD_TYPE
WHERE R1.FAVORITES = R2.MAX_FAVORITES
ORDER BY R1.FOOD_TYPE DESC;
'database' 카테고리의 다른 글
[Database 이론] Data models (0) | 2024.03.27 |
---|---|
[Database 이론] DB/DBMS/DB System (0) | 2024.03.27 |
[Database] SQL/ JOIN, MySQL LIMIT (0) | 2024.03.09 |
[Database] Group by/프로그래머스/식품분류별 가장 비싼 식품의 정보 조회하기 (0) | 2024.03.09 |