[Oracle] JOIN 쉽게 이해하기
데이터베이스/Oracle

[Oracle] JOIN 쉽게 이해하기

반응형

JOIN?

2개 이상의 테이블을 연결해서 데이터를 검색하는 방법

보통 두개이상의 행(ROW)들의 공통된 값 기본키(PRIMARY KEY), 외래키(FOREIGN KEY)를 사용해서 JOIN을 한다.

 

기본키(Primary key) : 테이블에서 레코드의 중복을 허용하지 않는 대표성을 가진 유일한 필드의 모음

기본키 필드 값은 중복되면 안되지만 기본키 필드를 제외한 필드 값은 중복돼도 상관없다

 

참조키, 외래키(Foreign key) : 테이블 간의 관계를 나타내는 필드의 모음


JOIN을 사용하는 목적?

현재 테이블에서 상대테이블의 정보(COLUMN)을 산출하기 위한 것


JOIN의 예시 구문 

[ANSI 표준]

SELECT 검색필드명

FROM 테이블명1

JOIN 테이블명2

ON 테이블명1(별명1).필드명1 = 테이블명2(별명2).필드명1

AND 테이블명1(별명1).필드명2 = 테이블명2(별명2).필드명2

WHERE 조건식;

 

[Oracle]

SELECT 검색필드명

FROM 테이블명1 (별명1),

테이블명2 (별명2)

WHERE 테이블명1(별명1).필드명1 = 테이블명2(별명2).필드명1(+);


JOIN의 종류

INNER JOIN

    =>기준 테이블과 대상 테이블에 매칭하는 필드값이 있는 경우에 검색한다.

 

LEFT JOIN

    =>기준 테이블의 모든 필드값을 보이고 대상 테이블에 매칭하는 필드값이 있는 경우에 검색하고, 그렇지 않으면 공백으로 보인다.

 

RIGHT JOIN
    =>LEFT JOIN의 반대되는 개념입니다.

 

FULL OUTER JOIN

    =>기준 테이블과 대상 테이블에 상호 매칭하는 필드값이 있는 경우에 검색하고, 그렇지 않으면 공백으로 보인다.

JOIN을 검색하면 바로 나오는 사진입니다. 아래 실습 내용을 보고 JOIN에 대해서 쉽게 이해하시고, 위 사진은 참고만 해주세요!


실제 두개의 테이블을 가지고 실습을 해보겠습니다!

1. 8월 성적 테이블(TB_GRADE_08)

SELECT * FROM TB_GRADE_08;

2. 9월 성적 테이블(TB_GRADE_09)

SELECT * FROM TB_GRADE_09;

두 테이블이 속한 시험코드(TEST_CD)로 JOIN을 해야 합니다. 

테이블을 확인해보면

8월 성적 테이블과 9월 성적 테이블에는 시험코드 'T01', 'T04', 'T07'을 공통으로 가지고 있고,

시험 코드 'T02', 'T09'는 8월 성적 테이블에만 있고,

시험 코드 'T05', 'T08'은 9월 성적 테이블에만 있습니다.

 

#1 INNER JOIN (두 테이블간 매칭되는 레코드만 검색)

두 테이블에 매칭되는 레코드만 검색하는 명령.

즉, 기준 테이블(TB_GRADE_08)과 대상 테이블(TB_GRADE_09)에서 TEST_CD 필드의 값이 매칭되는 'T01', 'T04', 'T07'을 검색

 

[ANSI]

SELECT A.TEST_CD, B.TEST_CD
FROM TB_GRADE_08 A
INNER JOIN TB_GRADE_09 B
ON A.TEST_CD = B.TEST_CD;

 

[Oracle]

SELECT A.TEST_CD, B.TEST_CD

FROM TB_GRADE_08 A, TB_GRADE_09 B
WHERE A.TEST_CD = B.TEST_CD;

  A.TEST_CD (기준) B.TEST_CD (대상)
1 T01 T01
2 T04 T04
3 T07 T07

#2 LEFT JOIN (기준 테이블을 기준으로 검색)

기준 테이블을 기준으로 검색하는 명령이다. 기준 테이블(TB_GRADE_08)의 모든 TEST_CD 필드의 값인 'T01', 'T02', 'T04', 'T07', 'T09'를 검색하고, 대상 테이블(TB_GRADE_09)에서는 TEST_CD 필드의 값과 매칭되는 'T01', 'T04', 'T07'은 검색하고, 그렇지 않은 'T02', 'T09'는 공백으로 출력 된다.

 

[ANSI]

SELECT A.TEST_CD, B.TEST_CD
FROM TB_GRADE_08 A LEFT JOIN TB_GRADE_09 B
ON A.TEST_CD = B.TEST_CD;

 

[Oralce]

SELECT A.TEST_CD "(08)", B.TEST_CD "(09)"
FROM TB_GRADE_08 A, TB_GRADE_09 B
WHERE A.TEST_CD = B.TEST_CD(+);

  A.TEST_CD (기준) B.TEST_CD (대상)
1 T01 T01
2 T02 <NULL>
3 T04 T04
4 T07 T07
5 T09 <NULL>

만약에 여기서 TB_GRADE_08만 가지고 있는 고유의 TEST_CD 'T02', T09'의 값만 출력하고싶다.

즉, TB_GRADE_09에서 NULL인 값!

SELECT A.TEST_CD "(08)", B.TEST_CD "(09)"
FROM TB_GRADE_08 A, TB_GRADE_09 B
WHERE A.TEST_CD = B.TEST_CD(+)
AND B.TEST_CD IS NULL;

  A.TEST_CD (기준) B.TEST_CD (대상)
1 T02 <NULL>
2 T09 <NULL>

쿼리문을 보면 기존 LEFT JOIN 에서 B.TEST_CD IS NULL( B.TEST_CD 가 NULL인 경우 )를 추가해주시면 됩니다.

RIGHT JOIN의 경우도 동일합니다!

 

#2 RIGHT JOIN (대상 테이블을 기준으로 검색)

 대상 테이블(TB_GRADE_09)의 모든 TEST_CD 필드의 값인 'T01', 'T04', 'T05', 'T07', 'T08'을 검색했고, 기준 테이블(TB_GRADE_08)에서는 TEST_CD 필드의 값과 매칭되는 'T01', 'T04', 'T07'은 검색하고, 그렇지 않은 'T05', T08'은 공백

 

[ANSI]

SELECT A.TEST_CD, B.TEST_CD
FROM TB_GRADE_08 A RIGHT JOIN TB_GRADE_09 B
ON A.TEST_CD = B.TEST_CD;

 

[Oracle]

SELECT A.TEST_CD "(08)", B.TEST_CD "(09)"
FROM TB_GRADE_08 A, TB_GRADE_09 B
WHERE A.TEST_CD(+) = B.TEST_CD;

  A.TEST_CD (기준) B.TEST_CD (대상)
1 T01 T01
2 T04 T04
3 <NULL> T05
4 T07 T07
5 <NULL> T08

#3 FULL OUTER JOIN (두 테이블 데이터를 모두 출력)

기준 테이블과 대상 테이블을 상호 검색하는 명령이다.

기준 테이블 (TB_GRADE_08)과 대상 테이블(TB_GRADE_09)에서 상호 TEST_CD 필드의 값이 매칭되는 'T01', 'T04', 'T07'은 검색하고 TB_GRADE_08을 기준으로 매칭되지 않는 'T02', 'T09' 와 TB_GRADE_09를 기준으로 매칭되지 않는 'T05', 'T08'은 공백으로 보인다.

 

[ANSI]

SELECT A.TEST_CD, B.TEST_CD
FROM TB_GRADE_08 A FULL OUTER JOIN TB_GRADE_09 B
ON A.TEST_CD = B.TEST_CD;

 

[Oracle]

SELECT A.TEST_CD, B.TEST_CD
FROM TB_GRADE_08 A, TB_GRADE_09 B
WHERE A.TEST_CD = B.TEST_CD(+)
UNION
SELECT A.TEST_CD, B.TEST_CD
FROM TB_GRADE_08 A, TB_GRADE_09 B
WHERE A.TEST_CD(+) = B.TEST_CD;

  A.TEST_CD (기준) B.TEST_CD (대상)
1 T01 T01
2 T04 T04
3 <NULL> T05
4 T07 T07
5 <NULL> T08
6 T09 <NULL>
7 T02 <NULL>

FULL OUTER JOIN에서 서로 NULL값인 경우만 출력하려면? (기준 테이블과 대상 테이블의 서로 NULL인 값)

SELECT A.TEST_CD, B.TEST_CD
FROM TB_GRADE_08 A FULL OUTER JOIN TB_GRADE_09 B
ON A.TEST_CD = B.TEST_CD
WHERE A.TEST_CD IS NULL
OR B.TEST_CD IS NULL;

  A.TEST_CD (기준) B.TEST_CD (대상)
1 <NULL> T05
2 <NULL> T08
3 T09 <NULL>
4 T02 <NULL>

 

참고 : 하루 10분 SQL

반응형