MySQL에서 같은 ID를 공유하는 여러 레코드가 있을 때, 특정 컬럼의 값(예: '예', '아니요')별로 개수를 집계해야 하는 경우가 자주 있습니다. 이럴 때는 SUM() 함수와 CASE 문 또는 조건식을 함께 활용하면 간단하게 해결할 수 있습니다.
MySQL에서는 조건식이 참일 때 1, 거짓일 때 0을 반환하기 때문에, sum(isMarried='Yes')처럼 조건식을 SUM() 안에 넣으면 해당 조건을 만족하는 행의 개수를 손쉽게 구할 수 있습니다.
1. 샘플 테이블 생성
먼저 예제에 사용할 테이블을 생성해 보겠습니다.
mysql> create table DemoTable1430
-> (
-> EmployeeId int,
-> isMarried ENUM('YES','NO')
-> );
Query OK, 0 rows affected (0.60 sec)
직원 ID(EmployeeId)와 결혼 여부(isMarried, ENUM 타입) 두 개의 컬럼으로 구성된 테이블입니다.
2. 데이터 삽입
insert 문을 사용하여 테스트용 레코드를 삽입합니다. 여기서는 의도적으로 동일한 직원 ID(1001)에 대해 서로 다른 값을 가진 레코드 여러 건을 넣었습니다.
mysql> insert into DemoTable1430 values(1001,'Yes');
Query OK, 1 row affected (0.19 sec)
mysql> insert into DemoTable1430 values(1001,'No');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable1430 values(1001,'Yes');
Query OK, 1 row affected (0.09 sec)
mysql> insert into DemoTable1430 values(1001,'Yes');
Query OK, 1 row affected (0.16 sec)
3. 저장된 데이터 확인
select 문으로 테이블의 전체 레코드를 조회해 보겠습니다.
mysql> select * from DemoTable1430;
실행 결과는 다음과 같습니다.
+------------+-----------+
| EmployeeId | isMarried |
+------------+-----------+
| 1001 | YES |
| 1001 | NO |
| 1001 | YES |
| 1001 | YES |
+------------+-----------+
4 rows in set (0.00 sec)
직원 ID 1001에 대해 'YES'가 3건, 'NO'가 1건 존재하는 것을 확인할 수 있습니다.
4. 값별 개수 집계 쿼리
이제 '예(Yes)'와 '아니요(No)' 값의 개수를 각각 집계하는 쿼리를 살펴보겠습니다. GROUP BY 절로 직원 ID별로 묶은 뒤, 조건식을 포함한 SUM() 함수를 사용합니다.
mysql> select EmployeeId,sum(isMarried='Yes') as NumberOfMarried,
-> sum(isMarried='No') as NumberOfUnMarried
-> from DemoTable1430
-> group by EmployeeId;
실행 결과는 다음과 같습니다.
+------------+-----------------+-------------------+
| EmployeeId | NumberOfMarried | NumberOfUnMarried |
+------------+-----------------+-------------------+
| 1001 | 3 | 1 |
+------------+-----------------+-------------------+
1 row in set (0.00 sec)
결과 해석
위 결과를 보면 직원 ID 1001에 대해 기혼('Yes') 레코드는 3건, 미혼('No') 레코드는 1건으로 정확하게 집계된 것을 알 수 있습니다.
참고로 CASE 문을 명시적으로 사용하고 싶다면 아래와 같이 작성할 수도 있으며, 결과는 동일합니다.
select EmployeeId,
sum(case when isMarried='Yes' then 1 else 0 end) as NumberOfMarried,
sum(case when isMarried='No' then 1 else 0 end) as NumberOfUnMarried
from DemoTable1430
group by EmployeeId;
이 방식은 값의 종류가 더 많아지거나 복잡한 조건이 필요할 때도 유연하게 확장할 수 있어 실무에서 널리 활용됩니다.