달력

52024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
프로그래밍/DB 2016. 9. 23. 10:25


SQL의 JOIN에서 ON과 WHERE의 차이점은 JOIN하는 범위가 다르다.
아래 두 SQL문을 보자. 두 SQL문 모두 LEFT JOIN을 수행하는 OUTER JOIN이다.

1)
SELECT *
FROM test1 a LEFT JOIN test2 b
ON (a.aa = b.aa)
WHERE b.cc = 7;

2)
SELECT *
FROM test1 a LEFT JOIN test2 b
ON (a.aa = b.aa AND b.cc = 7);


1)의 경우는 a와 b 테이블의 OUTER JOIN을 수행한 후에 b.cc = 7인 데이터들을 추출하지만
2)의 경우는 (a 테이블)과 (b 테이블 중 b.cc = 7인 경우)를 OUTER JOIN 한 결과가 나온다.

따라서 1)의 결과는 b.dd = 7인 데이터만 존재하지만
2)의 결과는 b.cc = 7이 아닌 데이터도 존재한다.
아래와 같은 test1, test2 테이블이 있을 때,

test1     test2
aa|bb      aa|cc
-----     -----
1 | 4        1 | 7
2 | 5       2 | 8
3 | 6


그 SQL의 결과는 다음과 같다.

1)
1|4|1|7

2)
1|4|1|7
2|5|null|null
3|6|null|null



한마디로 ON과 WHERE의 경우는 JOIN을 할 대상(범위)이 달라진다는 것이다.


여기서 OUTER JOIN을 가지고 차집합을 구현할 수 있다. 오라클이나 MSSQL과 같은 경우는 EXCEPT 혹은 MINUS 등을 사용하면 되겠지만 MySQL은 버전에 따라 지원하는 경우도 있고, 아닌 경우도 있다. Document 페이지에서 찾아보려 했으나 오늘따라 접속이 안된다. -ㅅ-;;

test1 테이블의 데이터 중 test2 테이블에 있는 데이터를 제외하고 가져오고 싶다. test2.aa에 있는 데이터가 test1.aa에 없는 데이터를 test1 테이블에서 가져온다는 것이다. 말이 어려운가 -ㅅ-a 한마디로 test1에서 3|6을 가지고 오고 싶은 것이다. 일단 SQL문을 보자 -ㅅ-;;;

SELECT *
FROM test1 a LEFT JOIN test2 b
ON (a.aa = b.aa)
WHERE b.aa IS NULL;


3|6|null|null


test2.aa에 있는 1, 2의 데이터를 제외한 데이터를 test1.aa에서 가져왔다. SQL문의 * 부분은 알아서 잘 세팅하여 사용하면 될 것이다. LEFT OUTER JOIN이기 때문에 WHERE절 이전까지 실행했을 때 아래와 같은 결과가 나온다.

1|4|1|7
2|5|2|8
3|6|null|null


여기에서 test2 테이블에 존재하지 않아서 test2 테이블의 column이 null인 부분만을 가지고 오게 WHERE절을 달아주면!! 차집합이 된다는 것이다.


출처 : http://egloos.zum.com/entireboy/v/2996500

'프로그래밍 > DB' 카테고리의 다른 글

INNER JOIN & OUTER JOIN의 차이  (0) 2016.09.23
절차형 SQL  (0) 2016.09.23
풀스캔을 방지  (0) 2016.09.23
Posted by 당구치는 개발자
|