[MSSQL] #1 IN, NOT IN 구문 설명 및 사용법(오류 케이스)
- DB/MS SQL
- 2021. 3. 25.
안녕하세요~!
이번 포스팅은 일전에 살펴보았던 IN 구문과 NOT IN 구문에 대해 살펴볼게요. :-)
(이와 연계해서 다음 포스팅은 EXISTS, NOT EXISTS문에 대해 포스팅해볼게요.)
2021.02.18 - [DB/MS SQL] - [MSSQL] IN절 사용법 및 예제
IN절에 대해 살펴보고, 활용법에 대한 내용이 있으니 참고하시면 좋을 것 같아요.
그럼 먼저, IN과 NOT IN 구문을 알아보겠습니다!!
1. IN 구문
IN절은 간단히 말해서 해당 컬럼들이 포함된 결과를 출력하는 문법으로 보시면 됩니다.
OR절을 많이 비교하는데, 문법이 약간 달라요.
이해를 돕기 위해, 우선 예시 테이블을 생성해보겠습니다.
<예시 테이블>
NO_COLOR | NM_COLOR | |
1 | 1 | RED |
2 | NULL | ORANGE |
3 | 2 | YELLOW |
4 | 3 | BLUE |
5 | 4 | PINK |
6 | 5 | NULL |
7 | 6 | WHITE |
8 | NULL | BLACK |
9 | 7 | NAVY |
10 | 8 | BROWN |
1.1. 사원테이블
NO_EMP | NM_KOR | |
1 | 1 | 이태백 |
2 | 2 | 복세복 |
3 | 3 | 전화복 |
4 | 4 | 김현욱 |
5 | NULL | 권태훈 |
6 | 5 | NULL |
7 | 6 | 박준수 |
8 | NULL | 김태산 |
1.2. 사원테이블
IN절 쿼리
SELECT *
FROM MA_COLOR C
WHERE C.NO_COLOR IN (SELECT E.NO_EMP FROM MA_EMP E)
위와 같은 쿼리를 실행했을 때의 결과는 아래와 같습니다!
NO_EMP | NM_KOR | |
1 | 1 | 이태백 |
2 | 2 | 복세복 |
3 | 3 | 전화복 |
4 | 4 | 김현욱 |
5 | 5 | NULL |
6 | 6 | 박준수 |
기본적으로 IN절에 대한 이해를 하셨다면, 위 결과는 예측이 가능하실 거에요.
제가 이 예시 테이블을 예로 설명드리고자 하는 부분은 IN이 포함된 쿼리가 어떻게 적용이 되는지
알아야 NOT IN, EXISTS 그리고 NOT EXISTS 구문에 대한 확실한 이해가 되실 거에요~!
1) 위의 쿼리는 1순위로 MA_EMP 테이블에 대한 접근을 합니다. :)
따라서, IN 뒤에 있는 괄호 안의 서브쿼리가 먼저 실행되고, 이에 대한 결과물(요소)을 출력합니다.
⁕IN절 뒤의 괄호 안에는 서브쿼리 뿐 아니라, 직접 값을 지정할 수도 있습니다.
2) 쿼리 내 1순위의 괄호 내 결과물을 가져온 후, 다음으로 MA_COLOR 테이블에서 하나의 컬럼을 가져옵니다.
해당 컬럼의 NO_COLOR 값이 앞에서 가져온 IN 뒤의 요소에 포함되어 있는지를 체크합니다.
또한, IN 이하의 요소들 중 하나라도 일치하게 되면 해당 컬럼을 출력하는 거에요!!
가장 중요한 포인트는!!
- 쿼리 내 MA_EMP 테이블 먼저 접근하여, NO_EMP 값들을 가져옵니다.
- 해당 컬럼의 값들을 IN 이하 구문에 출력합니다.
- 값들을 출력한 이후 MA_COLOR 테이블에서 하나의 컬럼씩 IN 이하의 요소들과 일치여부를 비교합니다. :)
해당 순서대로 쿼리가 작동하는 부분만 잘 숙지하고 계시면 좋을 것 같아요..!
2. NOT IN 구문
NOT IN 구문에 대해서도 함께 살펴볼건데요.
쿼리를 통해서 함께 내용을 보겠습니다~!
NOT IN절 쿼리
SELECT *
FROM MA_COLOR C
WHERE C.NO_COLOR NOT IN (SELECT E.NO_EMP FROM MA_EMP E)
쿼리 실행 결과는 아래 테이블과 같습니다.
NO_EMP | NM_KOR | |
> 어떤 데이터도 출력이 되지 않는 걸 확인할 수 있습니다!
위의 쿼리는 앞서 살펴본 IN절의 쿼리 방식을 참고해서 살펴보겠습니다. :)
- IN은 IN절 이하 괄호 안의 서브쿼리를 먼저 실행합니다.
- 그럼 (SELECT C.NO_EMP FROM MA_EMP E) 의 쿼리가 실행이 되고, 결과값이 리스트로 출력됩니다.
- 결과 값은 (1, 2, 3, 4, 5, 6, NULL) 값이 출력됩니다.
쿼리를 다시 풀어서보면,
SELECT * FROM MA_COLOR C
WHERE C.NO_COLOR NOT IN (1, 2, 3, 4, 5, 6, NULL)
이런 쿼리가 되겠죠??!
그렇다면, MA_EMP 테이블에서 하나의 컬럼씩 출력할 것이고
IN구문의 반대인 NOT IN 구문에 따라 괄호의 요소들과 일치하지 않는 결과들이 출력됩니다.
MA_COLOR 컬럼 중에서 <8/BROWN> 컬럼을 통해 살펴보면,
해당 컬럼인 NO_COLOR 값이 NOT IN 이하 구문(1, 2, 3, 4, 5, 6, NULL)에 있는지 확인해야 합니다.
NO_COLOR 값이 7과 8의 데이터는 존재하지 않아요!!
그렇다면, 해당 컬럼의 결과 7, 8 데이터는 출력이 되어야하는데 위와 같이 출력이 안된 이유는 무엇일까요?
데이터베이스에서 해당 요소가 NOT IN 이하 요소값들에 대한 포함여부를 어떻게 체크하는지를 알면 이해가 수월할거에요.
저도 처음엔 헷갈렸던 부분인데, 아래 판단하는 기준을 한번 살펴보겠습니다.
SELECT *
FROM MA_COLOOR C
WHERE C.NO_COLOR != 1
AND C.NO_COLOR != 2
AND C.NO_COLOR != 3
AND C.NO_COLOR != 4
AND C.NO_COLOR != 5
AND C.NO_COLOR != 6
AND C.NO_COLOR != NULL;
> 따라서 NOT IN 구문은 MA_COLOR 테이블에서 불러온 컬럼의 NO_COLOR의 값이
괄호 속의 모든 요소들과 일치하지 않는지를 체크합니다.
위의 쿼리에서는 NO_COLOR의 값이 NULL과도 연산을 진행하게 됩니다.
이에 대해 NULL과의 비교연산에 대한 반환 출력 값은 항상 UNKNOWN 값을 반환합니다.
다시 살펴보면, WHERE 조건절 이하 구문이 TRUE가 아니므로 해당 컬럼이 출력이 되지 않습니다.
다음과 같이 NOT IN의 쿼리가 적용되는 방식을 알고나서는 NOT IN 이하 구문의
MA_EMP의 NULL값 떄문에 출력하고자 했던 결과가 나오지 않음을 알 수 있었습니다.
기대하던 원하는 데이터를 얻기 위해서는 어떻게 할까요?!
SELECET * FROM MA_COLOR C
WHERE C.NO_COLOR NOT IN
(SELECT E.NO_EMP FROM MA_EMP E WHERE E.NO_EMP IS NOT NULL);
NO_COLOR | NM_COLOR | |
1 | 1 | RED |
3 | 2 | YELLOW |
4 | 3 | BLUE |
5 | 4 | PINK |
6 | 5 | NULL |
7 | 6 | WHITE |
> 해당 쿼리를 실행하면, 다음과 같은 결과가 출력됨을 알 수 있습니다.
이렇게 IN절 / NOT IN절에 대해서 살펴보았는데요~!
구문 안에서 쿼리가 어떻게 작동하는지를 숙지해놓으시면 좋을 것 같아요.
다음 포스팅에서는 EXISTS문 / NOT EXISTS문에 대해서도 살펴볼게요.
IN절을 먼저 이해한 후, EXISTS문에 대해서도 함께 공부해봅시다. :-)
'DB > MS SQL' 카테고리의 다른 글
[MSSQL] CASE WHEN 및 IF문 설명 및 사용법(조건문) (0) | 2021.04.05 |
---|---|
[MSSQL] #2 EXISTS, NOT EXISTS문 설명 및 사용법 (3) | 2021.03.28 |
[MSSQL] 데이터 형태 변환 CONVERT / CAST 함수 설명 및 사용법 (0) | 2021.03.21 |
[MSSQL] GROUP BY절 / HAVING절 / 집계함수 설명 및 사용법 (0) | 2021.03.17 |
[MSSQL] 공백제거 LTRIM/RTRIM 설명 및 사용법 (0) | 2021.03.10 |