MySQL에서 GROUP BY 절을 사용하면 NULL 값들은 기본적으로 하나의 그룹으로 묶여 단일 행으로 출력됩니다. 이러한 동작을 방지하고 NULL 값이 포함된 각 행을 개별적으로 유지하려면 IFNULL() 함수를 활용하면 됩니다. 아래에서 예제와 함께 자세히 살펴보겠습니다.
예제 테이블 생성
먼저 예제에 사용할 테이블을 생성합니다.
mysql> create table DemoTable1511
-> (
-> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> FirstName varchar(20)
-> );
Query OK, 0 rows affected (1.97 sec)
데이터 삽입
insert 명령을 사용하여 테이블에 레코드를 추가합니다. 이때 의도적으로 NULL 값도 함께 입력합니다.
mysql> insert into DemoTable1511(FirstName) values('John');
Query OK, 1 row affected (0.20 sec)
mysql> insert into DemoTable1511(FirstName) values('Robert');
Query OK, 1 row affected (0.29 sec)
mysql> insert into DemoTable1511(FirstName) values('Mike');
Query OK, 1 row affected (0.10 sec)
mysql> insert into DemoTable1511(FirstName) values('Robert');
Query OK, 1 row affected (1.08 sec)
mysql> insert into DemoTable1511(FirstName) values(NULL);
Query OK, 1 row affected (0.68 sec)
mysql> insert into DemoTable1511(FirstName) values(NULL);
Query OK, 1 row affected (1.91 sec)
mysql> insert into DemoTable1511(FirstName) values('Mike');
Query OK, 1 row affected (0.51 sec)저장된 전체 데이터 확인
select 문을 사용하여 테이블의 모든 레코드를 조회해 보겠습니다.
mysql> select * from DemoTable1511;
위 쿼리는 다음과 같은 결과를 출력합니다.
+----+-----------+
| Id | FirstName |
+----+-----------+
| 1 | John |
| 2 | Robert |
| 3 | Mike |
| 4 | Robert |
| 5 | NULL |
| 6 | NULL |
| 7 | Mike |
+----+-----------+
7 rows in set (0.00 sec)
NULL 값이 단일 행으로 축소되지 않도록 하는 쿼리
다음은 GROUP BY가 NULL 값들을 하나의 행으로 합치지 않도록 처리하는 쿼리입니다. 핵심은 GROUP BY 절에 ifnull(FirstName, Id)를 함께 지정하는 것입니다. FirstName이 NULL인 경우 해당 행의 고유한 Id 값으로 대체되기 때문에, 각 NULL 행이 서로 다른 그룹으로 분류됩니다.
mysql> select min(Id) as Id,FirstName from DemoTable1511 group by FirstName,ifnull(FirstName,Id) order by Id;
위 쿼리는 다음과 같은 결과를 출력합니다.
+------+-----------+
| Id | FirstName |
+------+-----------+
| 1 | John |
| 2 | Robert |
| 3 | Mike |
| 5 | NULL |
| 6 | NULL |
+------+-----------+
5 rows in set (0.00 sec)
결과 분석
출력 결과를 보면 NULL 값이 두 개의 개별 행(Id 5, Id 6)으로 그대로 유지된 것을 확인할 수 있습니다. 만약 단순히 GROUP BY FirstName만 사용했다면 두 NULL 행이 하나로 합쳐져 4개의 행만 반환되었을 것입니다.
반면 John, Robert, Mike처럼 값이 존재하는 이름들은 기존처럼 정상적으로 그룹화되며, min(Id)를 통해 각 그룹에서 가장 작은 Id 값이 대표값으로 출력됩니다. 즉, 이 방법은 일반 값의 그룹화 동작은 그대로 유지하면서 NULL 값만 개별 행으로 처리해야 할 때 매우 유용합니다.