Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL NOT IN 활용법: 중복 열 값 필터링을 위한 조건부 GROUP BY 구현하기

개요

MySQL에서 NOT IN 연산자와 서브쿼리를 활용하면, 특정 값만 반복해서 가진 레코드만 골라내는 조건부 GROUP BY 로직을 손쉽게 구현할 수 있습니다. 이번 글에서는 예제 테이블을 생성하고, NOT IN()을 사용해 원하는 결과를 추출하는 과정을 단계별로 살펴보겠습니다.

1단계: 테이블 생성

먼저 데모용 테이블을 생성합니다.

mysql> create table DemoTable
(
    Name varchar(40),
    Score int
);
Query OK, 0 rows affected (0.48 sec)

2단계: 레코드 삽입

INSERT 명령을 사용해 테이블에 샘플 데이터를 입력합니다.

mysql> insert into DemoTable values('Adam',89);
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable values('Adam',89);
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable values('Chris',89);
Query OK, 1 row affected (0.13 sec)
mysql> insert into DemoTable values('Chris',89);
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable values('Bob',98);
Query OK, 1 row affected (0.10 sec)
mysql> insert into DemoTable values('Bob',89);
Query OK, 1 row affected (0.16 sec)

3단계: 전체 데이터 확인

SELECT 문으로 테이블의 모든 레코드를 조회합니다.

mysql> select *from DemoTable;

실행 결과는 다음과 같습니다.

+-------+-------+
| Name  | Score |
+-------+-------+
| Adam  |    89 |
| Adam  |    89 |
| Chris |    89 |
| Chris |    89 |
| Bob   |    98 |
| Bob   |    89 |
+-------+-------+
6 rows in set (0.00 sec)

4단계: NOT IN()을 활용한 조건부 GROUP BY 쿼리 실행

아래 쿼리는 NOT IN() 서브쿼리를 사용하여, 점수가 89가 아닌 레코드를 하나라도 가진 이름은 제외하고 오직 89점만 기록한 이름들만 중복 없이 조회합니다.

mysql> select distinct Name from DemoTable where Name
not in(select Name from DemoTable where Score <> 89);

결과는 다음과 같습니다.

+-------+
| Name  |
+-------+
| Adam  |
| Chris |
+-------+
2 rows in set (0.06 sec)

쿼리 동작 원리

서브쿼리 select Name from DemoTable where Score <> 89는 점수가 89가 아닌 레코드의 이름 목록을 반환합니다. 위 예제에서는 98점을 받은 Bob이 여기에 해당하므로, 메인 쿼리의 NOT IN 조건에 의해 Bob은 최종 결과에서 제외됩니다. 반면 Adam과 Chris는 보유한 모든 레코드의 점수가 89이므로 결과에 포함되며, DISTINCT 키워드 덕분에 각각 한 번씩만 출력됩니다.

이처럼 NOT IN과 서브쿼리를 조합하면 별도의 복잡한 JOIN이나 HAVING 절 없이도, "특정 조건을 만족하지 않는 그룹 전체를 걸러내는" 필터링 로직을 간결하게 작성할 수 있습니다.