MySQL에서 특정 열에 대해 두 개 이상의 서로 다른 값을 가진 레코드를 조회하고 싶다면, GROUP BY 절과 HAVING 절을 함께 사용하는 것이 가장 효과적인 방법입니다.
1. 예제 테이블 생성
먼저 실습에 사용할 테이블을 생성합니다.
mysql> create table DemoTable751 (
StudentName varchar(100),
SubjectName varchar(100)
);
Query OK, 0 rows affected (0.66 sec)2. 샘플 데이터 삽입
INSERT 명령을 사용하여 학생 이름과 과목 데이터를 입력합니다.
mysql> insert into DemoTable751 values('John','MySQL');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable751 values('John','MongoDB');
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable751 values('Sam','MySQL');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable751 values('Carol','Java');
Query OK, 1 row affected (0.21 sec)
mysql> insert into DemoTable751 values('David','MySQL');
Query OK, 1 row affected (0.16 sec)
mysql> insert into DemoTable751 values('Carol','MongoDB');
Query OK, 1 row affected (0.17 sec)3. 전체 데이터 확인
SELECT 문으로 테이블에 저장된 모든 레코드를 확인해 보겠습니다.
mysql> select *from DemoTable751;
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
+-------------+-------------+ | StudentName | SubjectName | +-------------+-------------+ | John | MySQL | | John | MongoDB | | Sam | MySQL | | Carol | Java | | David | MySQL | | Carol | MongoDB | +-------------+-------------+ 6 rows in set (0.00 sec)
결과를 보면 John은 MySQL과 MongoDB, Carol은 Java와 MongoDB라는 서로 다른 두 과목을 수강하고 있으며, Sam과 David는 각각 하나의 과목만 수강한 것을 알 수 있습니다.
4. 두 개 이상의 서로 다른 값을 가진 레코드 조회
여기서 핵심이 되는 쿼리입니다. GROUP BY로 학생 이름별로 그룹화한 뒤, HAVING 절에서 과목 개수가 1보다 큰 그룹만 필터링합니다.
mysql> select StudentName from DemoTable751 group by StudentName having count(SubjectName) > 1;
실행 결과는 다음과 같습니다.
+-------------+ | StudentName | +-------------+ | John | | Carol | +-------------+ 2 rows in set (0.00 sec)
쿼리 동작 원리 정리
WHERE 절은 그룹화되기 전의 개별 행에 조건을 적용하지만, HAVING 절은 GROUP BY로 그룹화된 결과 집합에 조건을 적용한다는 점이 핵심입니다. 따라서 COUNT() 같은 집계 함수의 결과를 기준으로 필터링할 때는 반드시 HAVING 절을 사용해야 합니다.
이 방법을 응용하면 주문 내역에서 여러 상품을 구매한 고객을 찾거나, 게시판에서 여러 카테고리에 글을 작성한 사용자를 추출하는 등 다양한 실무 시나리오에 활용할 수 있습니다.