MySQL오류 - SELECT list is not in GROUP BY clause and contains nonaggregated column

Posted by Geuni's Blog on April 16, 2022

오류 메시지:

1
[42000][1055] Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mydb.t.address' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

MySQL 5.7.5 및 그 이상 버전부터 디폴트로 ONLY_FULL_GROUP_BY옵션이 enable된 상태이다.

GROUP BY쿼리에서 SELECT,ORDER BY,HAVING절에 nonaggregated 컬럼을 참조할때 SQL-92표준에 위배되며 따라 ONLY_FULL_GROUP_BY모드에서 해당오류가 발생한다.(예외case 참고)

아래는 MySQL 5.7의 sql_mode 기본값이다.ONLY_FULL_GROUP_BY mode를 확인할수 있다.

mysql_sql_mode

단지 현재 작성중인 쿼리가 발생한 오류라면 재확인하여 다시 쓰면된다.

DB엔진 레벨에서 해당 오류를 해결할기를 원하면 sql_mode중 ONLY_FULL_GROUP_BY모드를 disable하면 된다.(이미 생산환경에서 운영중일때 해당모드를 enable할떄는 신중할것, 프로젝트 초기부터 해당옵션을 enable시켜 표준SQL을 작성할수있도록 제약을 주는게 좋음)

my.cnf파일에

1
2
3
4
5
6
7
8
9
10
vi /usr/local/etc/my.cnf

# config파일이 어디 있는지 모를때 아래와 같이 조회가능.
➜  ~ which mysqld
/usr/local/opt/mysql@5.7/bin/mysqld

➜  ~ /usr/local/opt/mysql@5.7/bin/mysqld --verbose --help | grep -A 1 "Default options"
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf

아래와 같이 sql_mode옵션을 추가한다.(기존값에서 ONLY_FULL_GROUP_BY만 제거)

1
2
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

재구동후 적용됨.

runtime모드에서도 해당옵션 변경이 가능하다.(재구동 필요없음)

1
2
3
4
5
## global레벨
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

# session레벨
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

작업완료후 적용여부 확인:

1
2
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;