MySQL에서 특정 조건을 만족하는 StudentId가 발견되면, 해당 ID를 가진 모든 행을 결과에서 제외해야 하는 경우가 있습니다. 이럴 때는 서브쿼리(subquery)와 NOT IN 연산자를 활용하면 간단하게 해결할 수 있습니다.
1. 테이블 생성하기
먼저 예제에 사용할 테이블을 생성합니다.
mysql> create table DemoTable1427
-> (
-> StudentId int,
-> StudentMarks int
-> );
Query OK, 0 rows affected (1.28 sec)
2. 데이터 삽입하기
INSERT 문을 사용하여 몇 개의 레코드를 추가합니다.
mysql> insert into DemoTable1427 values(201,89);
Query OK, 1 row affected (0.13 sec)
mysql> insert into DemoTable1427 values(201,99);
Query OK, 1 row affected (0.18 sec)
mysql> insert into DemoTable1427 values(210,98);
Query OK, 1 row affected (0.16 sec)
3. 전체 레코드 조회하기
SELECT 문으로 테이블의 모든 레코드를 확인합니다.
mysql> select * from DemoTable1427;
위 쿼리는 다음과 같은 결과를 출력합니다.
+-----------+--------------+
| StudentId | StudentMarks |
+-----------+--------------+
| 201 | 89 |
| 201 | 99 |
| 210 | 98 |
+-----------+--------------+
3 rows in set (0.00 sec)
4. 서브쿼리로 특정 행 제외하기
이제 핵심 쿼리입니다. StudentMarks가 89인 행을 가진 StudentId 201은 동일한 ID로 또 다른 레코드(StudentMarks 99)도 함께 가지고 있습니다. 따라서 StudentId 201에 해당하는 모든 행이 결과에서 제외됩니다.
mysql> select * from DemoTable1427
-> where StudentId NOT IN (select distinct StudentId from DemoTable1427 where StudentMarks=89);
실행 결과
+-----------+--------------+
| StudentId | StudentMarks |
+-----------+--------------+
| 210 | 98 |
+-----------+--------------+
1 row in set (0.00 sec)
쿼리 동작 원리 정리
이 쿼리의 작동 방식을 단계별로 살펴보면 다음과 같습니다.
1단계: 내부 서브쿼리가 먼저 실행되어 StudentMarks = 89 조건을 만족하는 행들의 StudentId 목록을 추출합니다. 여기서는 201이 해당됩니다.
2단계: 외부 쿼리는 NOT IN 조건을 사용하여 해당 StudentId 목록에 포함되지 않는 행만 반환합니다.
결과: StudentId 201의 두 행(89점, 99점)이 모두 제외되고, StudentId 210의 행(98점)만 최종 결과로 출력됩니다.
이처럼 서브쿼리와 NOT IN을 조합하면, 특정 값이 하나라도 발견된 그룹 전체를 손쉽게 필터링할 수 있습니다. 참고로 대량의 데이터를 다룰 때는 성능 향상을 위해 JOIN 방식이나 EXISTS 절을 대안으로 고려해볼 수도 있습니다.