[SQL error] MySQL Handling of GROUP BY
mysql sql문 오류...
Error Code: 1055. Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mydatabase.menus.price' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 0.00035 sec
원인) GROUP BY [Column1, Column2...]의 column에 포함되어 있는 열이 아니라면 SELECT list, HAVING condition, or ORDER BY list에 비집계 열(nonaggregated column)을 포함시킬 수 없다.
집계 열이라고 하는 것은...count, max, sum(열)과 같은 방식으로 표현한 식을 의미한다. 반면, 비집계 열이란, 아래의 c.name과 같은 열을 의미한다.
예를 들면, 위와 같이 name이라는 열을 SELECT list포함시키면 위와 같은 에러를 볼 수 있다.
단, custid가 PK일 경우, 종속성을 파악할 수 있기 때문에 쿼리가 유효하다.
해결-1) [GROUP BY 이하] 집계 함수 이 외에 필요한 모든 열을 추가한다.
SELECT col1, col2, COUNT(col3) FROM TABLE
GROUP BY col1, col2 //원하는 기준이 외에도 추가적으로 비집계 열까지도 포함
해결-2) ANY_VALUE(c.name)으로 포함시키면 쿼리가 유효하다.
- 아래와 같이 ANY_VALUE를 하게 되면, col1로 그룹화된 행 중에 col2값이 달라도 하나만 보여주는 것으로, col1, col2와 1:1 매칭이 될 경우에 사용하는 것이 좋을 듯 하다.
SELECT col1, ANY_VALUE(col2), COUNT(col3) FROM TABLE
GROUP BY col1 //원하는 기준이 외에도 추가적으로 비집계 열까지도 포함
해결-3) sql_mode 에서 ONLY_FULL_GROUP_BY 설정을 뺀다
▶ mysql로 접속한다음 아래 코드를 치면 설정을 해제할 수 있다.
mysql > SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
fk_business에 딸린 menu_name이 2가지씩(오른쪽 사진) 있지만,
2,3번 방식의 경우에는 첫번째 값(왼쪽 사진)만 표현한다.
이는 오해의 소지가 있을 수 있으니 설정값을 해제하는 방법은 좋지 않아보인다.
결론)
GROUP BY할 경우, 필요한 열은 GROUP BY에 추가하는 1번 방식을 채택.
간혹, col1, col2가 1:1 매칭되는 속성을 가질 때는 ANY_VALUE로 SELECT list에 포함시키는 방식을 사용해야겠다.
// 해제했던 ONLY_FULL_GROUP_BY는 다시 되돌려 놓자..
SET sql_mode = 'ONLY_FULL_GROUP_BY';
** 틀린 부분이 있으면 댓글 부탁드립니다.
** 똑같은 실수는 없도록 기록하고 성장하기!
**참고 문헌
https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html