개발 일기

[MySQL] GROUP BY 와 ONLY_FULL_GROUP_BY 본문

Computer Science/Database

[MySQL] GROUP BY 와 ONLY_FULL_GROUP_BY

개발 일기장 주인 2024. 8. 28. 16:09

창업팀에서 로직 요구 사항이 변경되어서 게시글 페이징 조회 시에 댓글 수를 추가적으로 조회해야 했다.

쿼리 내용

내용 중에 쿼리는 다음과 같은데 GROUP BY를 사용하게 됐다.

그런데

다음과 같은 에러가 발생하면서 500이 터졌다. 로그를 번역해보면 아래와 같았다.

Error Code: 1055. SELECT 목록의 Expression #1이 GROUP BY 절에 포함되어 있지 않으며, 열 'woomzip.u.nickname'이 GROUP BY 절의 열에 기능적으로 종속되지 않은 비집계 열을 포함하고 있습니다. 이는 sql_mode=only_full_group_by와 호환되지 않습니다.

사실 잘 와닿지 않았다.

이 오류는 MySQL에서 ONLY_FULL_GROUP_BY 모드가 활성화되어 있을 때 발생하는데 이 모드는 GROUP BY 절에 명시된 열 들 외에 다른 열이 SELECT 목록에 포함되었을 때, 해당 열이 집계 함수로 감싸져 있지 않으면 오류를 발생시킨다.

즉, p.post_id만이 아니라그 뒤에 u.user_img_url까지 모두 group_by절에 포함시켜야 한다.

이렇게 하면 200으로 되는 것을 확인할 수 있었다.


ONLY_FULL_GROUP_BY

ONLY_FULL_GROUP_BY는 MySQL의 SQL 모드 중 하나로, GROUP BY 절을 사용할 때 보다 엄격한 기준을 적용하여 쿼리의 정확성을 높이기 위한 설정이다. 이 모드가 활성화되면 GROUP BY 절에 포함되지 않은 모든 열은 반드시 집계 함수(예: COUNT, SUM, MAX, MIN 등)로 감싸져야 한다. 그렇지 않으면 오류가 발생한다.

 

sql_mode의 ONLY_FULL_GROUP_BY 옵션이 꺼져있으면 다음과 같은 문제가 생길 수 있습니다.

  • 쿼리가 잘못되었다는 것을 알 수 없음
  • 의미 없는 열이 표시될 수 있음
  • 실행된 결과가 원하는 결과가 아닐 수 있음

그래도 옵션을 끄고 싶다면?

select @@sql_mode;

# 현재 연결에만 적용(DB 재접속하면 해제)
set @@sql_mode = replace(@@sql_mode, 'ONLY_FULL_GROUP_BY', '');

# 전역 설정 적용(재접속시 적용)
set global sql_mode = replace(@@sql_mode, 'ONLY_FULL_GROUP_BY', '');

set global sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

이렇게 쿼리로 처리가능하고

 

직접 설정파일을 건드린다면 ubuntu에

여기 설정파일에 (window라면 my.ini)

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

다음 sql_mode에 대한 설정을 추가해주면 된다.