LEFT OUTER JOIN 을 사용 했을때 JOIN 절에 조건식을 넣는것과 JOIN 이후 WHERE을 이용해서 조건식을 넣는것의 차이점 및 *=는 전자를 이야기 한다
-------------------------------------------------------------------------------------------------------
출처 : http://blog.naver.com/crabz/140023357168
MSSQL의 left outer join과 *= 는 같은 표현이 아닙니다. (전혀 다름)
예를 들어 다음과 같은 테이블이 있습니다.
select * from A;
YM EMP DEPT
200212 1 40
200212 2 40
200212 3 40
200212 4 40
200212 5 40
200212 6 40
200212 7 40
200212 8 40
select * from B;
YM EMP DEPT
200212 1 40
200212 2 40
200212 3 40
200212 4 40
(1)
select count(*)
from A left outer join B
on A.emp = B.emp
where A.ym = '200212'
and B.ym='200212'
and A.dept='40';
result : 4
(2)
select count(*)
from A , B
where A.emp *= B.emp
and A.ym = '200212'
and B.ym='200212'
and A.dept='40';
result : 8
직접 돌려보시면 확인 가능하듯이
위의 적은 바와 같이 결과가 다르게 나옵니다.
많은 사람들이
MSSQL에서
LEFT Outer Join 과 *=는 동의어라고 생각하지만 사실은 그렇지 않습니다.
LEFT Outer Join과 *= 는 의미적으로 다른 사용입니다.
MSSQL의 *= 을 사용하지 말라는 권고사항을
단지 과거의 사용형식이기 때문이라고 생각하기 때문에 흘려듣는데..(일부 책에도 그렇게 소개되
기도 했지만..)
*=이 소개되었을때 ANSI에서는 Outer 조인에 대하여 어떠한 표준이나 사양이 존재하지 않았습니
다. 이런 문제로 ANSI위원회에서는 Outer 조인의 올바른 의미와 구현원칙을 제정하였고 이후
MSSQL 6.5에서 ANSI OUTER JOIN이 체택되었습니다.
즉 *= 는 이전의 MSSQL의 하위버전을 위해 지원하는 이전의 'MSSQL식'의 Outer JOIN 형식입니다.
둘의 근본적인 차이는 이렇습니다.
1구문의
and B.ym='200212'
는 아웃터 조인이 일어난후에 조건 체크가 되고
2구문의
and B.ym='200212'
는 아웃터 조인이 일어나기전에 조건 체크가 됩니다.
즉 1구문에서 4개의 행밖에 나오지 않은것은
OUTER JOIN을 한 후에 B.ym='200212' 조건에 의해
B.ym이 Null 인것을 제외하였기 때문입니다.
반면에 2구문에서 8개의 행이 나온것은
조인이 일어나기 전에 B테이블의 4건을 선택하는 조건으로
and B.ym='200212'이 이용되고
그 이후에 Outer Join이 실행되었습니다.
상황에 따라 다른 조건을 추가로 기입해서 같은 결과가 나오도록 할수 있으나
이를테면
1의 구문을
and (BB.ym = '200212' or BB.ym is null ) 식으로 수정하여야 합니다.
(그러나 이것도 B의 ym 컬럼이 Not Null이 아니라면 같은 결과를 보장할수 없습니다.. )
이런 미묘한 차이는 찾기 어려운 버그를 양산시키므로
말 그대로 *= 식의 사용법은 "권장하지 않습니다."