2009년 8월 18일 화요일

[Oracle에서의 Minus] MSSQL에서 구현하는 방법은 없을까?

MSSQL에서 MINUS기능 구현하기

 

Oracle 에서 두 테이블의 차이를 알고 싶을때는 간단하게 minus 기능을 이용해서 값을 구할 수 있습니다.

 

예)

A테이블에서 B테이블을 빼기

SELECT * FROM TABLE_A

MINUS

SELECT * FROM TABLE_B

 

B테이블에서 A테이블을 빼기

SELECT * FROM TABLE_B

MINUS

SELECT * FROM TABLE_A

 

 

결과: A 테이블에는 존재하지만 B 테이블에는존재하지 않는 모든 레코드

(그러므로 양 테이블의 모든 차분레코드를 가지고 오려면 B 테이블에서도 A테이블을 MINUS 해줘야 합니다.)

 

그렇다면 MSSQL(SQL SERVER) 에서는 어떻게 MINUS 기능을 구현 할까요?

따로 명령어가 있는게 아니라 SQL쿼리로 구현해야 합니다.

 

A테이블에서 B테이블을 빼기

SELECT * FROM TABLE_A

WHERE NOT EXIST ( SELECT * FROM TABLE_B B

                            WHERE KEY1 = B.KEY1 AND KEY2 = B.KEY2 )

 

B테이블에서 A테이블을 빼기

SELECT * FROM TABLE_B

WHERE NOT EXIST ( SELECT * FROM TABLE_A B

                            WHERE KEY1 = B.KEY1 AND KEY2 = B.KEY2 )

 

이렇게 하면 ORACLE에서의 MINUS와 같은 검색결과가 나올까요??? 저도 그런듯 했으나..아니였습니다

뭐가 문제냐면 키값만 비교해서 다른걸 가져오니 당근 컬럼속 다른값이 틀리면 아무 소용이 없습니다.

(이 쿼리는 비교할 테이블의 키 값만을 서로 비교한다면 유효한 쿼리겠죠!!^^)

 

그럼 무식하게 전 컬럼을 다 비교 해야겠다고 생각해봤죠....

 

A테이블에서 B테이블을 빼기

SELECT * FROM TABLE_A

WHERE NOT EXIST ( SELECT * FROM TABLE_B B

                            WHERE KEY1 = B.KEY1 AND KEY2 = B.KEY2

                                And Column3 = B.Column3

                                And Column4 = B.Column4

                                And Column5 = B.Column5

                                ...

                                And ColumnN = B.ColumnN)

 

 

B테이블에서 A테이블을 빼기

SELECT * FROM TABLE_B

WHERE NOT EXIST ( SELECT * FROM TABLE_A B

                            WHERE KEY1 = B.KEY1 AND KEY2 = B.KEY2

                                And Column3 = B.Column3

                                And Column4 = B.Column4

                                And Column5 = B.Column5

                                ...

                                And ColumnN = B.ColumnN)

 

이렇게 하면 만족하는 결과를 얻을 수 있을까요? 언뜻 보면 완벽하게 두 테이블을 비교 가능 한것처럼 보입니다. 하지만 다양하게 테스트를 하다보면 역시 아니구나 하는 생각이 듭니다.

바로 NULL 값 비교가 문제가 되죵... MSSQL(SQL SERVER)에서나 ORACLE 에서  NULL 값은  어떤 값과도 비교가 되지 안는다는 특징을 가지고 있습니다. 어떻게 보면 NULL이란 값은 존재하지도 않는 값이라서 비교한다는 것 자체가 말이 안되는 것일 수 도 있습니다.

 

결과적으로 완성된 쿼리를 만들어 보면 아래와 같습니다.

 

A테이블에서 B테이블을 빼기

SELECT * FROM TABLE_A

WHERE NOT EXIST ( SELECT * FROM TABLE_B B

                            WHERE KEY1 = B.KEY1 AND KEY2 = B.KEY2

                                And ISNULL(Column3,'') = ISNULL(B.Column3,'')

                                And ISNULL(Column4,'') = ISNULL(B.Column4,'')

                                And ISNULL(Column5,'') = ISNULL(B.Column5,'')

                                ...

                                And ISNULL(ColumnN,'') = ISNULL(B.ColumnN,''))

 

 

B테이블에서 A테이블을 빼기

SELECT * FROM TABLE_B

WHERE NOT EXIST ( SELECT * FROM TABLE_A B

                            WHERE KEY1 = B.KEY1 AND KEY2 = B.KEY2

                                And ISNULL(Column3,'') = ISNULL(B.Column3,'')

                                And ISNULL(Column4,'') = ISNULL(B.Column4,'')

                                And ISNULL(Column5,'') = ISNULL(B.Column5,'')

                                ...

                                And ISNULL(ColumnN,'') = ISNULL(B.ColumnN,''))

 

ISNULL함수를 이용해서 NULL값을 공백 값으로 변경한다음 비교를 하면 끝 입니다..^^

ORACLE에서 MINUS 처럼 깔끔하게 결과를 도출하기에는 컬럼수가 많아지면 어렵지만 결과적으로

정확하게 비교하는게 중요한거겠죵.^^

 

우측상단에 첨부파일에 예제를 올려놨습니다 참고하세요

 

대한민국 개발자 여러분 홧팅하세요..

 

 

 

 

 

 

 

 

댓글 없음:

댓글 쓰기