food, color 두개의 table 이 있다.
이때 not in과 in이 어떻게 행동하는지 알아보자
먼저 알아야하는 것은 null연산은 unkown이다.
먼저
IN
in 은 내부쿼리를 통해 list를 만들고 외부쿼리의 값과 비교한다. ( 내부쿼리 -> 외부쿼리)
not IN은 unkown을 미포함한다.
"=" 연산과 같다.
select * from food where number in (select number from color);
먼저 내부쿼리를 통해 list를 만든다. color의 number이므로 {1, 2, 3, 4, null }이다.
이를 food 테이블의 number와 비교한다.
null과 null의 연산은 unkown이고, in에서는 미포함이므로 null은 출력되지않는다.
즉, food의 number( 1, 2 ,3 ,4 ,5, null) 중 5, null 은 포함되지않으므로 number가 1,2,3,4 인 튜플만 출력된다.
NOT IN
select * from food where number not in (select number from color);
이 select 문을 보면
먼저 color에서 number을 뽑아서 list를 만든다음 food의 number에 없는 것을 찾아 출력하겠구나 라는 생각이든다.
list를 생각해보자
{ 1 , 2 , 3 , 4 , null } 이일것이다.
food의 number는 1 , 2 , 3 , 4 , 5 , null 이다.
처음 드는 생각은 5가 list에 포함되어있지않으니까 5, bread가 출력되려나! 이다.
하지만 틀렸다.
사진처럼 아무것도 출력되지않는다.
그 이유를 한문장으로 설명하면 null 연산은 unkown이 되고, not in 은 unknown을 미포함하기 때문이다.
[in은 요소간에 각각 비교연산을 한다. => food의 number값이 list의 모든 요소들과 일치여부를 확인한다. ]
list의 null이 존재하기 때문에 각각 비교할때, null 과의 연산이 포함된다. null 과의 연산은 unkown이 되고,
in은 unkown을 포함하지않으므로(in은 '=' 과 같은데 not in은 !=을 의미한다고 생각하면 != 은 unknown과 다르므로)
모든 튜플이 출력되지않는것이다.
이것을 생각대로 출력하고 싶다면 not in 쿼리 안에서 list에 null이 들어가지 않도록
where number is not null 코드를 추가시키면 된다.
select * from food where number not in (select number from color where number is not null);
EXISTS
exists 은 외부쿼리를 통해 레코드를 가져와 내부쿼리에 값이 "존재하는지" 확인한다. ( 외부쿼리 -> 내부쿼리)
NOT EXISTS은 unkown을 포함한다.
select * from food where exists (select number from color);
내부쿼리에 비교구문(where절)이 없어서 외부쿼리의 값들이 모두 출력된다.
select * from food where exists (select number from color where food.number = color.number);
내부쿼리에 where절을 추가하여 조건을 주었다. where절은 number를 비교하여 '=' 인것을 조건으로 만들었다.
'=' 과 null의 연산값인 unknown 은 다르므로 서브쿼리 결과는 null값을 포함하지않는다.
즉 , 1, 2, 3, 4 가 서브쿼리이고 exists는 존재여부를 따지므로 food의 1, 2, 3, 4가 출력된다.
NOT EXISTS
select * from food where not exists (select number from color where food.number = color.number);
food table에서 number를 가져오면 1 , 2 , 3 , 4 , 5 , null 이고, 서브쿼리에는 1 ,2, 3, 4 이 존재한다.
not exists이므로 서브쿼리에 값이 존재하지않는 튜플을 찾는다.
{ 1 , 2 , 3 , 4 , 5 , null } 에서 1, ,2, 3, 4 는 서브쿼리에 존재하지 않은 number는 5, null이다.
(null을 비교하면 unknown 이고 not exists는 unknown을 포함한다. 즉 food의 number가 null인 튜플도 출력한다.)
[exists는 그냥 존재여부를 따진다 라고 생각하면 편하다.]
참고 블로그 :
https://doorbw.tistory.com/222
[MS SQL Server] #11_ IN / EXISTS / NOT IN / NOT EXISTS 비교
안녕하세요 문범우입니다. 이번 포스팅에서는 IN, EXISTS, NOT IN, NOT EXISTS 에 대해서 보다 상세하게 알아보려고 합니다. 해당 내용은 꼭 SQL Server 뿐만 아니라 MySQL 등에서도 포괄적으로 적용되는 내
doorbw.tistory.com
지적, 조언 환영합니다.
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
'3-2 > DB' 카테고리의 다른 글
[mysql][프로그래머스]SQL 고득점 kit 답!! (0) | 2022.03.04 |
---|---|
[프로그래머스][join][mysql]없어진 기록찾기(left join ,right join) (0) | 2022.02.24 |
[mysql]Workbench_ER다이어그램 그리는 법 (0) | 2021.12.10 |
[Mysql]Trigger생성과 삭제(feat. delimiter) (0) | 2021.10.25 |
MySQL 기본 실습 - show databases(1) (0) | 2021.09.10 |