강의로 돌아가기
이태현

`GROUP BY` 구 사용이 헷갈리는 분들을 위하여 - MySQL의 내부적인 작동 옵션과 관련한 설명

아래와 같은 Orders 테이블이 있다고 가정해봅시다.

+------+---------+-------+
| id   | revenue | month |
+------+---------+-------+
| 1    | 8000    | Jan   |
| 2    | 7000    | Jan   |
| 3    | 6000    | Jan   |
+------+---------+-------+

만약 우리가 month 필드를 기준으로 revenue 필드의 값들 중 가장 큰 값을 반환하고 그 값의 id 필드의 값도 반환하고 싶다면 어떻게 해야 할까요? 해당 문제를 푸는 접근 방식은 이번 문제와 유사합니다. 그래서 만약 아래와 같이 쿼리문을 작성하면 어떻게 될까요?

SELECT
  id,
  month,
  MAX(revenue) AS revenue
FROM Orders
GROUP BY month

revenue 필드의 값은 집계함수 MAX를 사용했기 때문에 복수의 필드 중 어떤 값을 반환해야 하는지 결정이 되었고 month 필드 또한 GROUP BY 구의 기준이기 때문에 반환해야 하는 값이 명확히 정해져 있습니다. 그런데 id 필드는 어떨까요? 그룹으로 묶이기 전을 한 번 테이블로 표시하면 아래와 같은 상태일 겁니다.

+------+---------+-------+
| id   | revenue | month |
+------+---------+-------+
| 1    | 8000    | Jan   |
| 2    | 8000    | Jan   |
| 3    | 8000    | Jan   |
+------+---------+-------+

다시 말해 DBMS 입장에서는 어떤 id 필드의 값을 반환해야 하는지 알 수 없기 때문에 오류를 반환하게 됩니다. 이게 기본적인 MySQL의 작동 방식입니다. 그런데 프로그래머스에서 위 쿼리를 실행하면 아마 오류가 발생하지 않고 id 필드의 값으로 1 혹은 어떤 값들 중 임의의 값 하나를 무작위로 반환할 것입니다.

이는 MySQL 내에 존재하는 sql_mode 값 때문입니다. 관련해서 자세한 내용은 MySQL 공식 문서의 SQL 모드 부분을 확인하시길 바랍니다.

먼저 아래와 같이 프로그래머스가 어떤 sql_mode 값을 가지고 있는지 조회해보면 NULL이 반환되는 걸 확인할 수 있습니다.

SELECT @sql_mode;

우리의 상황에서는 GROUP BY 부분이 궁금하므로 MySQL의 SQL 모드 중 GROUP BY 구와 연관된 ONLY_FULL_GROUP_BY라는 옵션이 sql_mode 테이블의 값으로 존재하는지 확인해보면 되는데 위에서 확인해본 것처럼 프로그래머스의 MySQL 서버에는 어떤 값도 존재하지 않습니다.

ONLY_FULL_GROUP_BY 옵션의 경우 기본적으로는 존재하며 이 값이 존재할 경우 GROUP BY 구를 사용할 때 집계 함수 등으로 선택되지 못해 임의의 값 중 어떤 값을 반환해야 할 지 모르는 필드가 존재하면 오류를 반환하게 되어있습니다. 그런데 프로그래머스 MySQL 서버의 경우 어떠한 모드도 취하고 있지 않고 있기 때문에 해당 ONLY_FULL_GROUP_BY 옵션이 꺼져있는 상태입니다. 따라서 결과적으로 MySQL 내부에서 어떤 값을 골라야 할 지 모르는 임의의 값 중 무작위로 하나의 값을 고르게 되고 보통 자동적으로 가장 첫 번째 값을 고르게 되어 있습니다.

다시 원점으로 돌아와서, 결국 GROUP BY 구의 기준이 되는 필드가 아니거나 집계 함수를 통해 어떤 값을 반환해야 할 지 결정해주지 않은 필드를 SELECT 구에 사용할 경우 문법적으로 틀린 SQL 구문입니다. GROUP BY 구 사용과 관련하여 헷갈리는 분들은 이 부분 유의하여 한 번 다시 접근해보면 좋을 것 같습니다.

  • 최진우

    감사합니다 많은 도움됬습니다!

    최진우―2022.12.04 14:03
  • 박민호

    감사합니다ㅠㅠ

    박민호―2023.02.10 23:07
9 개의 답변
JoDongHyuen

좋은 글 감사합니다!

SooHyun Kim

많은 도움이 되었네요. 감사합니다!

KERORO

와 감사합니다!

배재완

감사합니다

HwangHanJae

감사합니다!

78alswo79

감사합니다..group by를 남발하는 오류를 범하면 안되겠네요

Lee Yongseung

GROUP BY 사용 규칙에 대해 깔끔하게 정리해 주셔서 감사합니다.

qnwk810

와 감사합니다!!

byeolhaha

감사합니다!

답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다. 마크다운 가이드 를 참고하세요.