2015-01-13 3 views
0

두 테이블이 있으며 두 테이블 모두 하나의 열만 있습니다. delete_DimCSI에는 196194 개의 행이 있고 delete_FRO에는 195740 개의 행이 있습니다. delete_DimCSI 테이블에있는 행을 찾고 있는데 delete_FRO 테이블에 없습니다.이 쿼리가 작동하지 않는 이유는 무엇입니까

이것이 내가 일반적으로 사용하는 쿼리이며 지금까지 일했다 : 그것은 0 행을 반환

select PK_CSI from delete_DimCSI 
where PK_CSI not in (select FK_CSI from delete_FRO) 

.

select PK_CSI, FK_CSI from delete_DimCSI 
LEFT OUTER JOIN delete_FRO FRO on FK_CSI = PK_CSI 
where FK_CSI is null 

그것은 455 ​​개 행을 반환 :

은 그럼이 하나 만들었습니다.

첫 번째 쿼리가 아무런 결과를 반환하지 않는 이유는 무엇입니까?

+1

두 번째 쿼리가 해당 열의 두 테이블을 조인하고 외래 키가 null이거나 해당 PK_CSI가있는 행을 모두 선택했기 때문에 추측 할 수 있습니다. 첫 번째 쿼리는 NULL 값을 무시하는 NOT IN을 사용합니다. 대신 나는 존재하지 않는 것을 선호합니다. http://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join –

+0

가능한 중복 [NOT IN 절 및 NULL 값] (http://stackoverflow.com/questions/129077/) not-in-clause-and-null-values) –

답변

3

당신은 아마에 대한 설명 FK_csi

select PK_CSI from delete_DimCSI 
where PK_CSI not in (select FK_CSI from delete_FRO WHERE FK_CSI IS NOT NULL) 

hereNULL의가 있습니다.

+1

사실 ... 당신은 방금 몇 년 전에이 문제가 있다고 생각 나게했습니다 :) –

1

NOT IN은 부질의가 NULL 값일 때 이상하게 동작합니다. 이 경우 NULL 또는 false를 반환하며 어느 것도 true로 처리되지 않습니다.

이 때문에 NOT IN 대신 NOT EXISTS을 사용하는 것이 좋습니다. 미하이 알 수 있듯이

select PK_CSI 
from delete_DimCSI d 
where not exists (select 1 from delete_FRO f where f.FK_CSI = d.PK_CSI); 

물론, 당신은 또한 명시 적 where f.FK_CSI = NULL`을 추가 할 수 있습니다 의미는 당신이 기대하는 것 이상이다.

관련 문제