DataBase/MySql

MySql - GroupBy 및 ONLY_FULL_GROUP_BY 파헤치기

jaycheol 2025. 4. 1. 10:26
반응형

GROUP BY에 대한 설명

GROUP BY는 SQL에서 데이터를 그룹화하여 집계(aggregation) 함수를 적용할 때 사용됩니다. GROUP BY는 데이터를 하나의 기준으로 묶고, 각 그룹에 대해 계산을 수행하도록 합니다. 예를 들어, 부서별 평균 급여나, 제품별 총 판매액 등을 계산할 때 사용됩니다.

기본 구문

SELECT 컬럼명, 집계함수(컬럼명)
FROM 테이블명
GROUP BY 그룹화할_컬럼;
  • 그룹화할_컬럼: 데이터를 그룹화할 기준이 되는 컬럼입니다.
  • 집계함수: COUNT(), SUM(), AVG(), MAX(), MIN()과 같은 함수가 해당 그룹에 대해 계산을 수행합니다.

예시: 부서별 평균 급여 구하기

SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id;

이 쿼리는 employees 테이블에서 department_id별로 직원들의 salary 평균을 구합니다.

ONLY_FULL_GROUP_BY SQL 모드

MySQL에서 ONLY_FULL_GROUP_BY 모드는 GROUP BY 절을 사용할 때의 규칙을 엄격하게 적용하는 설정입니다. 이 모드에서는 GROUP BY 절에 포함되지 않은 컬럼을 SELECT에서 사용할 수 없습니다. 모든 컬럼은 반드시 GROUP BY 절에 포함되어야 하거나, 집계 함수(COUNT(), AVG(), SUM() 등)로 감싸야 합니다.

왜 ONLY_FULL_GROUP_BY 모드에서 문제가 발생할까?

ONLY_FULL_GROUP_BY 모드에서 GROUP BY 절을 사용하면 SQL 쿼리가 데이터의 정확성을 보장할 수 있도록 강제됩니다. 예를 들어, GROUP BY에 포함되지 않은 컬럼을 SELECT에서 사용하면 MySQL은 그 값을 어떻게 계산해야 할지 알 수 없습니다. 즉, 그룹화된 데이터 내에서 SELECT할 컬럼이 정확하게 어떤 값을 가져야 하는지 명확하지 않기 때문에 오류가 발생합니다.

오류 설명:

ONLY_FULL_GROUP_BY 모드에서 GROUP BY를 사용할 때 발생하는 오류는 다음과 같습니다:

Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'programmers.B.FISH_NAME' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by.

이 오류는 GROUP BY에 포함되지 않은 컬럼을 SELECT에서 사용했기 때문에 발생합니다. MySQL은 해당 컬럼을 집계 함수로 처리하거나, GROUP BY 절에 추가해야 한다고 요구합니다.

해결 방법:

  1. GROUP BY 절에 모든 컬럼 추가: GROUP BY 절에 SELECT에 사용된 모든 컬럼을 추가합니다.
  2. 집계 함수 사용: GROUP BY에 포함되지 않은 컬럼을 집계 함수로 감쌉니다.

예시들

예시 1: 오류 발생 예시

SELECT B.FISH_TYPE, B.FISH_NAME, COUNT(*) AS FISH_COUNT
FROM FISH_INFO A
JOIN FISH_NAME_INFO B ON A.FISH_TYPE = B.FISH_TYPE
GROUP BY B.FISH_TYPE;

여기서는 GROUP BY 절에 B.FISH_NAME을 추가하여 FISH_TYPE과 FISH_NAME을 기준으로 그룹화합니다. 이렇게 하면 FISH_NAME을 SELECT에서 사용할 수 있습니다.

예시 3: 오류 해결 2 - 집계 함수 사용

SELECT B.FISH_TYPE, MAX(B.FISH_NAME) AS FISH_NAME, COUNT(*) AS FISH_COUNT
FROM FISH_INFO A
JOIN FISH_NAME_INFO B ON A.FISH_TYPE = B.FISH_TYPE
GROUP BY B.FISH_TYPE;

여기서는 FISH_NAME을 집계 함수 MAX()로 감싸서, 각 FISH_TYPE에 대해 FISH_NAME을 하나의 값으로 처리합니다. MAX()는 여러 값을 하나로 합치는 함수로, 각 FISH_TYPE에 대해 가장 큰 FISH_NAME 값을 반환합니다.

예시 4: GROUP_CONCAT 사용

FISH_NAME 컬럼에 여러 개의 이름이 있을 수 있으므로 이를 하나의 문자열로 합치는 방법으로 GROUP_CONCAT() 함수를 사용할 수 있습니다.

SELECT B.FISH_TYPE, GROUP_CONCAT(B.FISH_NAME) AS FISH_NAMES, COUNT(*) AS FISH_COUNT
FROM FISH_INFO A
JOIN FISH_NAME_INFO B ON A.FISH_TYPE = B.FISH_TYPE
GROUP BY B.FISH_TYPE;

여기서는 GROUP_CONCAT()을 사용하여 같은 FISH_TYPE에 해당하는 FISH_NAME들을 하나의 문자열로 합칩니다. 예를 들어, 같은 FISH_TYPE을 가진 여러 물고기 이름이 있을 경우, 이를 쉼표로 구분된 문자열로 반환할 수 있습니다.

요약:

  • GROUP BY를 사용할 때, SELECT에서 사용되는 모든 컬럼은 GROUP BY 절에 포함되거나 집계 함수로 감싸야 합니다.
  • ONLY_FULL_GROUP_BY 모드는 이 규칙을 엄격히 적용하여, GROUP BY에 포함되지 않은 컬럼을 SELECT에서 사용할 수 없도록 합니다.
  • 오류를 해결하려면 GROUP BY 절에 해당 컬럼을 추가하거나, 집계 함수를 사용하여 처리할 수 있습니다.
반응형