MySQL 오류 1111(HY000)이 발생하는 이유
MySQL에서 WHERE 절에 AVG(), SUM(), COUNT() 같은 집계 함수(aggregate function)를 직접 사용하면 오류 1111(HY000): Invalid use of group function 에러가 발생합니다. 그 이유는 WHERE 절이 행(row) 단위로 필터링되는 단계에서 실행되는 반면, 집계 함수는 모든 행을 대상으로 계산한 결과를 반환하기 때문입니다. 즉, 아직 그룹화되지 않은 시점에서 집계 결과를 비교하는 것은 논리적으로 불가능합니다.
이 문제를 해결하려면 서브쿼리(subquery)를 활용해야 합니다. 서브쿼리가 먼저 평균값 등의 집계 결과를 계산하고, 외부 쿼리의 WHERE 절이 그 결과와 각 행을 비교하는 구조가 됩니다.
WHERE 절과 함께 집계 함수를 올바르게 사용하는 기본 문법
MySQL에서 WHERE 절과 집계 함수를 함께 사용할 때의 올바른 문법은 다음과 같습니다.
SELECT * FROM yourTableName
WHERE yourColumnName > (SELECT AVG(yourColumnName) FROM yourTableName);
위 문법을 실제 예제를 통해 자세히 살펴보겠습니다.
예제 테이블 생성하기
먼저 직원 정보를 저장할 테이블을 생성합니다. 테이블 생성 쿼리는 다음과 같습니다.
mysql> CREATE TABLE EmployeeInformation
-> (
-> EmployeeId int,
-> EmployeeName varchar(20),
-> EmployeeSalary int,
-> EmployeeDateOfBirth datetime
-> );
Query OK, 0 rows affected (1.08 sec)
샘플 데이터 삽입하기
INSERT 명령어를 사용해 테이블에 몇 개의 레코드를 추가합니다.
mysql> INSERT INTO EmployeeInformation VALUES(101,'John',5510,'1995-01-21');
Query OK, 1 row affected (0.13 sec)
mysql> INSERT INTO EmployeeInformation VALUES(102,'Carol',5600,'1992-03-25');
Query OK, 1 row affected (0.56 sec)
mysql> INSERT INTO EmployeeInformation VALUES(103,'Mike',5680,'1991-12-25');
Query OK, 1 row affected (0.14 sec)
mysql> INSERT INTO EmployeeInformation VALUES(104,'David',6000,'1991-12-25');
Query OK, 1 row affected (0.23 sec)
mysql> INSERT INTO EmployeeInformation VALUES(105,'Bob',7500,'1993-11-26');
Query OK, 1 row affected (0.16 sec)
전체 레코드 조회하기
SELECT 문으로 테이블의 모든 레코드를 확인합니다.
mysql> SELECT * FROM EmployeeInformation;
실행 결과는 다음과 같습니다.
+------------+--------------+----------------+---------------------+
| EmployeeId | EmployeeName | EmployeeSalary | EmployeeDateOfBirth |
+------------+--------------+----------------+---------------------+
| 101 | John | 5510 | 1995-01-21 00:00:00 |
| 102 | Carol | 5600 | 1992-03-25 00:00:00 |
| 103 | Mike | 5680 | 1991-12-25 00:00:00 |
| 104 | David | 6000 | 1991-12-25 00:00:00 |
| 105 | Bob | 7500 | 1993-11-26 00:00:00 |
+------------+--------------+----------------+---------------------+
5 rows in set (0.00 sec)
집계 함수를 활용한 올바른 쿼리 실행
이제 WHERE 절에서 서브쿼리와 함께 집계 함수를 사용하여, 전체 직원의 평균 급여보다 많이 받는 직원만 조회해 보겠습니다.
mysql> SELECT * FROM EmployeeInformation
-> WHERE EmployeeSalary > (SELECT AVG(EmployeeSalary) FROM EmployeeInformation);
실행 결과는 다음과 같습니다.
+------------+--------------+----------------+---------------------+
| EmployeeId | EmployeeName | EmployeeSalary | EmployeeDateOfBirth |
+------------+--------------+----------------+---------------------+
| 105 | Bob | 7500 | 1993-11-26 00:00:00 |
+------------+--------------+----------------+---------------------+
1 row in set (0.04 sec)
정리 및 추가 팁
5명 직원 급여의 평균은 약 6,058이며, 이보다 높은 급여를 받는 직원은 Bob(7,500) 한 명뿐입니다. 이처럼 서브쿼리를 사용하면 오류 1111 없이 원하는 결과를 얻을 수 있습니다.
참고로, 조건이 그룹별 집계 결과와 비교해야 하는 경우에는 WHERE 절 대신 HAVING 절을 사용하는 것이 좋습니다. HAVING 절은 GROUP BY로 그룹화된 이후의 결과에 대해 필터링을 수행하므로, 집계 함수를 직접 사용할 수 있습니다. 상황에 맞게 WHERE(행 단위 필터링 + 서브쿼리)와 HAVING(그룹 단위 필터링)을 구분해서 사용하면 됩니다.