Create table Test01(gubun1 varchar(2) null, gubun2 varchar(2) null)
Create table Test02(gubun1 varchar(2) null, gubun2 varchar(2) null)
insert into Test01 values ('01','A')
insert into Test01 values ('01','B')
insert into Test01 values ('01','C')
insert into Test01 values ('02','A')
insert into Test01 values ('02','B')
insert into Test01 values ('02','C')
insert into Test01 values ('03','A')
insert into Test01 values ('03','B')
insert into Test01 values ('03','C')
insert into Test02 values ('01','A')
insert into Test02 values ('01','B')
insert into Test02 values ('01','C')
insert into Test02 values ('01','D') -- Test01 에 존재하지 않음
insert into Test02 values ('02','A')
insert into Test02 values ('02','B')
--insert into Test02 values ('02','C')
--insert into Test02 values ('03','A')
--insert into Test02 values ('03','B')
--insert into Test02 values ('03','C')
insert into Test02 values ('04','A') -- Test01 에 존재하지 않음
insert into Test02 values ('04','B')-- Test01 에 존재하지 않음
select * from Test01
select * from Test02
--test01 에는 존재하지 않는데 Test02 에는 존재하는것 쿼리
select gubun1, gubun2 from Test02 where gubun1 not in (select distinct gubun1 from test01) or gubun2 not in (select distinct gubun2 from test01) --1
select gubun1, gubun2 from Test02 where gubun1 not in (select distinct gubun1 from test01) and gubun2 not in (select distinct gubun2 from test01) --2
위 두 쿼리의 실행계획표을 보면 전혀 다르게 작동을 합니다.
전 2번으로 쿼리로 생각했었는데 1번처럼 해야 원하는 결과을 얻을스 있었습니다.
어떻게 처리되는건지 설명좀 부탁드립니다.
감사합니다.
Comment 3
-
항해자™
2015.10.28 01:28
-
루디먼트
2015.10.28 10:35
설명을 덧붙이자면, where에 not in 조건으로 2개를 넣은 것이 문제인 것 같은데요.
1번은 2개의 조건 중 하나만 만족하면 결과가 나오고,
2번은 2개의 조건 모두 만족해야 결과가 나오는 것 이죠.
1번의 경우
gubun1의 not in 결과는 '04'가 나왔고, gubun2의 not in 결과는 'D'가 나왔는데 or 이므로 '04' 모든 row와 'D' 모든 row가 출력되겠죠.
만약 Test01 테이블에 '02','D' 데이터가 있었다면 결과는 의도하지 않게 나올 수 있겠네요.
2번의 경우
gubun1의 not in 결과는 '04'가 나왔고, gubun2의 not in 결과는 'D'가 나왔는데 and 이므로 '04' 이면서 'D' 를 만족하는 데이터가 없으므로 출력되는 결과가 없겠네요.
-
희망나라
2015.10.28 13:58
답변감사드립니다.
쿼리는 알면 알수록 신기하네요..
좋은하루 보내세요.
실행해 보지는 않았는데, left join을 사용하시는게 좀 더 직관적일 수 있습니다.
select a.*
from dbo.Test02 as a
left join dbo.Test01 as b
on b.gubun1 = a.gubun1
and b.gubun2 = a.gubun2
where b. gubun1 is null