본문 바로가기

STUDY/SQL, DB

[MySQL] - Invalid use of group function

 Leetcode에서 아래와 같은 문제를 풀었다.

570. Managers with at Least 5 Direct Reports

Table: Employee
+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
| department  | varchar |
| managerId   | int     |
+-------------+---------+
id is the primary key (column with unique values) for this table.
Each row of this table indicates the name of an employee, their department, and the id of their manager.
If managerId is null, then the employee does not have a manager.
No employee will be the manager of themself.
 
Write a solution to find managers with at least five direct reports.
Return the result table in any order.
The result format is in the following example.

 
Example 1:

Input: 
Employee table:
+-----+-------+------------+-----------+
| id  | name  | department | managerId |
+-----+-------+------------+-----------+
| 101 | John  | A          | null      |
| 102 | Dan   | A          | 101       |
| 103 | James | A          | 101       |
| 104 | Amy   | A          | 101       |
| 105 | Anne  | A          | 101       |
| 106 | Ron   | B          | 101       |
+-----+-------+------------+-----------+
Output: 
+------+
| name |
+------+
| John |
+------+

 

managerId가 5개 이상 나온 사람의 이름을 출력하는 것.

그리 어렵지 않게 풀 수 있을 것 같아 자신만만하게 쿼리를 써 내려갔는데 결과는? 보기좋게 에러! 아예 실행도 안 됐다.

 

-- 처음 풀이
select e2.name
  from employee e1
  join employee e2
    on e1.managerId = e2.id
  where count(e2.id) >= 5
  group by e2.id;
  
  
-- Runtime Error
Invalid use of group function

 

Invalid use of group function.

group 함수에 문제가 있다고? 잘 쓴 것 같은데? => 역시나 틀린 건 나였다.

 

 

기초중의 기초!... 인 것 같은 사실!

 

 WHERE절에는 집계함수를 쓸 수 없다!

 

집계함수는 COUNT, AVG, SUM, MAX, MIN, ... 등이 있다.  이는 쿼리문 실행 순서와 관련 있다.

 

WHERE절 다음에 GROUP BY가 실행된다.

 그런데 집계함수는, 말 그대로 "집계'함수니까 그룹화가 되어야 쓸 수 있는데 WHERE절에 나와버리면 그룹화 전이기 때문에 실행이 안 되는 것.

 

나는 집계함수를 이용해 조건을 걸어 줄 것이었으므로, 아래와 같이 고쳐주면 된다.

-- 고친 쿼리
select e2.name
  from employee e1
  join employee e2
    on e1.managerId = e2.id
  group by e2.id
  having count(e2.id) >= 5;

 

 

** GROUP BY에 대해 헷갈렸던 것들을 좀 더 정리해보았다.

 

 1. SQL을 배울 때, GROUP BY에 쓰인 컬럼은 꼭 SELECT 절에 나와야 한다! 는 말을 많이 봤다. 그런데 사실 안 나와도 실행은 됨. 다만, 얻고자 하는 결과가 제대로 나오지 않을 수 있으므로 되도록이면 그렇게 하라, 는 정도의 가이드라인.

 2. GROUP BY로 그룹화된 컬럼을 SELECT로 출력하려는 경우, 집계함수를 써 주지 않아도 출력이 되긴 하지만 원하는 결과를 얻기 위해선 집계함수를 써야 한다.

 3. HAVING절은 그룹화 된 결과에 조건을 걸어주는데에 쓰이므로, 여기 쓰이는 컬럼은 GROUP BY에서 그룹화 된 컬럼이거나, 그렇지 않다면 집계함수가 적용되어야 한다.