[MSSQL] #2 EXISTS, NOT EXISTS문 설명 및 사용법
- DB/MS SQL
- 2021. 3. 28.
이번 포스팅에서는 EXISTS 구문과 NOT EXISTS구문에 대해 알아보겠습니다.
EXISTS문은 IN문과 연계해서 살펴보면, 이해에 도움이 되실 거에요.
2021.03.25 - [DB/MS SQL] - [MSSQL] #1 IN, NOT IN 구문 설명 및 사용법(오류 케이스)
EXISTS문?
EXISTS 구문은 문장 안에 데이터 존재유무를 판단할 수 있는 문법입니다.
또한, EXISTS는 INSERT나 UPDATE 구문 처리 시에 많이 활용할 수 있습니다.
한 테이블이 다른 테이블과 외래키(FK)와 같은 관계가 있을 때 유용하며,
EXISTS는 두 테이블 간의 결과를 어떤 값이 존재하는 지를 알고 싶은 경우 활용합니다.
=> 데이터가 존재하는지를 판단하는 것이 핵심입니다. :)
지금부터 예시 테이블을 통해 EXISTS문을 활용하는 방법에 대해 알아볼게요.🙌
<예시 테이블1>
NO_COLOR | NM_COLOR | |
1 | 1 | RED |
2 | 2 | BLUE |
3 | NULL | BLACK |
4 | 3 | NULL |
5 | 4 | WHITE |
6 | NULL | NAVY |
<예시 테이블2>
NO_EMP | NM_KOR | |
1 | NULL | 복태욱 |
2 | 1 | NULL |
3 | 2 | 박세인 |
4 | NULL | 권태준 |
5 | 3 | 이치원 |
6 | 4 | NULL |
SELECT문을 활용한 구문을 통해 살펴보면,
SELECT * FROM MA_COLOR C
WHERE EXISTS (SELECT E.NO_EMP FROM MA_EMP);
NO_COLOR | NM_COLOR | |
1 | 1 | RED |
2 | 2 | BLUE |
3 | NULL | BLACK |
4 | 3 | NULL |
5 | 4 | WHITE |
6 | NULL | NAVY |
해당 쿼리로 실행할 경우, 다음과 같은 결과가 나오게 됩니다.🤔
예상과는 다른 결과라고 생각할 수도 있는데, 구조를 같이 살펴볼까요~?
위의 쿼리를 기준으로 데이터베이스가 어떻게 동작하는지 한번 알아보겠습니다.
위에 IN구문 살펴본 게시글을 참고하면,
IN구문에서는 IN절 이후에 나오는 소괄호 내부의 서브쿼리에 대해서 먼저 접근하였습니다.
하지만!! EXISTS 구문에서는 IN구문과는 차이가 있습니다.
- MA_COLOR 테이블에 접근해서 하나의 레코드를 가져옵니다.
- EXISTS 이하의 서브쿼리를 실행하고 서브쿼리에 대한 결과가 '존재하는지'를 확인합니다.
예를 들면,
- 가장 먼저 [ 1, RED ] 라는 레코드를 가져옵니다.
- 해당 레코드에 대해 SELECT E.NO_EMP FROM MA_EMP E 쿼리를 통해 결과가 나오는지 확인합니다.
- 이 때, 서브쿼리에 대해 어떠한 결과라도 존재하기만 한다면 참이 되어서 [ 1, RED ] 레코드가 출력됩니다.
중요한 점은 SELECT E.NO_EMP FROM MA_EMP E 쿼리는
MA_COLOR의 어떠한 레코드하고도 연관이 없이 항상 결과값을 가지는 쿼리에요. :)
따라서 MA_COLOR 테이블의 모든 레코드가 출력되는 것입니다!
그렇다면, 번호가 일치하는 결과를 출력하기 위해선 어떻게 구문을 활용해야할까요?!
SELECT * FROM MA_COLOR C
WHERE EXISTS (SELECT E.NO_EMP FROM MA_EMP E WHERE E.NO_EMP = C.NO_COLOR)
NO_COLOR | NM_COLOR | |
1 | 1 | RED |
2 | 2 | BLUE |
4 | 3 | NULL |
5 | 4 | WHITE |
이렇게 나온 결과는 사실 IN 구문과 같은 결과를 출력합니다.
하지만!! 내부적으로 쿼리가 동작하는 방식은 다르다는 것에 주의하시길 바랍니다.
이러한 내부 로직에 따라서 성능 차이가 크게 발생하기 때문에 알아두도록 합시다.😃
다음은 NOT EXISTS 구문에 대해 살펴보겠습니다.
NOT EXISTS문?
NOT EXISTS에 대해서도 위에서 살펴본 EXISTS문에 대한 이해를 하셨다면 큰 어려움이 없이 활용하실 수 있을 거에요.
NOT IN과는 차이가 있겠죠~?
SELECT * FROM MA_COLOR C
WHERE NOT EXISTS (SELECT E.NO_EMP FROM MA_EMP E WHERE E.NO_EMP = C.NO_COLOR)
NO_COLOR | NM_COLOR | |
1 | NULL | BLACK |
2 | NULL | NAVY |
앞의 NOT IN 구문에서 살펴보았을 경우에는
NO_COLOR 값이 NULL인 레코드는 출력되지 않았습니다.
(위 링크 게시글 참조)
그 이유를 다시 한번 생각해보면,
IN 구문은 요소간의 비교 연산으로 레코드를 출력하는데 NULL 값에 대한 비교연산은 항상 UNKNOWN을 반환하기 때문이었습니다.
하지만!! 위에서 살펴보았을 때 EXISTS 구문은 IN과는 다르게 동작하는 걸 확인할 수 있었죠?
위 쿼리를 기준으로 살펴보겠습니다.
- MA_COLOR 테이블에서 레코드를 가져옵니다.
- 해당 레코드의 NO_COLOR 값을 NOT EXISTS 이하의 서브쿼리에 전달하여 해당 서브쿼리에서 값이 존재하는지를 확인합니다.
- NOT EXISTS 구문이기에 해당 서브쿼리의 값이 존재하지 않으면 해당 레코드를 출력합니다.
⁕EXISTS 구문이었다면 값이 존재할 때 해당 레코드를 출력합니다.
NULL이 출력되는 과정을 자세하게 알아보게 되면,
[ NULL, BLACK ] 레코드를 예로 우선 살펴볼게요.
NO_COLOR = NULL 입니다.
따라서 NOT EXISTS 이하의 쿼리를 확인해보면 다음과 같을 것 입니다.
SELECT E.NO_EMP FROM MA_EMP E WHERE E.NO_EMP = NULL
이 때, NOT IN에서 알아본 것과 동일하게 NULL에 대한 비교연산은 항상 UNKNOWN 값을 반환합니다.
따라서 해당 쿼리의 결과가 존재하지 않게 되고, [ NULL, BLACK ] 레코드가 출력되는 것입니다.
IN구문과 EXISTS 구문은 많이 헷갈리기도 하고, 동일한 결과값에 대한 구문이 달라지기도 합니다.
따라서 두 구문의 차이를 잘 이해하시면 좋을 것 같아요~!
저도 다시 공부하면서 정리를 한번 더 했습니다!! 화이팅👏
'DB > MS SQL' 카테고리의 다른 글
[MSSQL] MERGE 구문 설명 및 사용법 (데이터 입력/수정/삭제) (0) | 2021.04.18 |
---|---|
[MSSQL] CASE WHEN 및 IF문 설명 및 사용법(조건문) (0) | 2021.04.05 |
[MSSQL] #1 IN, NOT IN 구문 설명 및 사용법(오류 케이스) (1) | 2021.03.25 |
[MSSQL] 데이터 형태 변환 CONVERT / CAST 함수 설명 및 사용법 (0) | 2021.03.21 |
[MSSQL] GROUP BY절 / HAVING절 / 집계함수 설명 및 사용법 (0) | 2021.03.17 |