JOIN 이란?
- 한개가 아니라, 여러개의 테이블에서 정보를 가져와서 결과를 만들어 주는 기법
- 관계형 데이터베이스 (RDBMS) 의 가장 핵심 기술중 하나
- 표준화된 ANSI형 JOIN 방식이 있고, 각각의 DBMS마다 다른 사용방식이 있으나
본문에서는 ANSI와 ORCLE만 다룬다.

JOIN의 종류
여러개의 테이블 중 어떤 테이블을 기준으로 데이터를 가져올것인지에 따라 JOIN의 이름이 다르다.
다음 (1)~(5)를 먼저 보고 (6)을 보자.
(1) Inner Join
: 테이블 간의 공통 요소 (교집합)

(2) Left Join
: 왼쪽 테이블의 데이터 + 테이블 간의 공통 요소

(3) Right Join
: 오른쪽 테이블의 데이터 +테이블 간의 공통 요소

(4) Full Join
: 테이블들의 모든 요소

(5) Cross Join
: 테이블간의 결합에 있어서 모든 가능한 경우의 수의 데이터를 나열

위의 JOIN들은 Join에 참여하는 테이블에 값이 있을 경우에만 결과값을 얻는다.
이를 큰 개념에서 Inner Join이라고 한다.
그런데 만약 임의의 테이블인 A와 B테이블을 Join해서 (A U B)의 모든 필드를 얻으려고 할 때,
B테이블의 특정 필드가 null값을 포함해서 비어있다면,
(1)~(5)의 방식으로는 A와 B의 온전한 Join 결과를 얻을 수 없다.
따라서 레코드가 부분적으로 null값을 포함하더라도,
null값은 null값인대로 출력할 수 있어야하고 이를 수행하는 Join문이 바로 Outer Join문이다.
(6) Outer Join
: 한쪽 테이블에 데이터가 있고 한쪽테이블에 없는 경우 데이터가 있는 쪽 테이블의 내용을 전부 출력
Outer Join에는 Left Outer Join, Right Outer Join, Full Outer Join 등이 있다.

JOIN의 사용
1) Equi Join (등가 Join) : Join의 결과가 특정 조건값과 '일치' 할 때
Ex1 t_student 테이블과 t_department 테이블을 사용하여 학생이름(name), 1전공 학과번호(deptno1),
1전공 학과 이름(dname) 을 출력하라
-- Oracle 방식 --
= SELECT s.name "학생이름", s.deptno1 "학과번호", d.dname "학과이름"
FROM t_student s, t_department d WHERE s.deptno1 = d.deptno;
-- ANSI 방식 --
= SELECT s.name "학생이름", s.deptno1 "학과번호", d.dname "학과이름"
FROM t_student s JOIN t_department d ON s.deptno1 = d.deptno;

1 >>> JOIN은 두개 이상의 테이블이 필연적으로 쿼리문에 등장하므로, 테이블에 대한 별칭을 사용해서
쿼리문 내에서 사용되는 필드가 어떤 테이블의 소속인지 알려줄 필요가 있다.
FROM t_student s, t_department d WHERE s.deptno1 = d.deptno;
2 >>> DBMS마다 쿼리문을 작성하는 방식의 차이가 있다. 앞에서 언급했듯 본문에서는 ANSI와 ORCLE만 다룬다.
Ex2 t_student 테이블, t_department 테이블, t_professor 테이블 을 join하여
‘학생이름(name)’, ‘학과이름(dname)’, ‘지도교수이름(name)’ 을 출력하라
-- Oracle 방식 --
= SELECT s.name "학생이름", d.name "학과이름" p.name "교수이름"
FROM t_student s, t_department d, t_professor p
WHERE s.deptno1 = d.deptno AND s.profno = p.profno;
-- ANSI 방식 --
= SELECT s.name "학생이름", d.name "학과이름" p.name "교수이름"
FROM t_student s
JOIN t_department d
ON s.deptno1 = d.deptno
JOIN t_professor p
ON s.profno = p.profno;

2) Non Equi Join (비등가 Join) : Join의 결과가 특정 조건 범위에 내에 존재할 때


Ex3 t_customer 테이블, t_gift 테이블이 위와 같을 때 join하여 고객의 마일리지 포인트별로
받을수 있는 상품을 조회하고 고객의 '이름(c_name)'과 포인트(c_point) 상품명(g_name)을 출력하라
(단, t_gift 테이블의 g_start와 g_end는 포인트범위의 시작과 끝을 나타내고 있다)
-- Oracle 방식 --
= SELECT c.c_name "고객명", c.c_point "포인트", g.g_name "상품명"
FROM t_customer c, t_gift g
WHERE c.c_point BETWEEN g.g_start AND g.g_end;
-- 고객의 포인트값이 기프트의 상한선과 하한선 포인트 사이에 존재해야하므로 BETWEEN~IN사용
-- ANSI 방식 --
= SELECT c.c_name "고객명", c.c_point "포인트", g.g_name "상품명"
FROM t_customer c JOIN t_gift g
ON c.c_point BETWEEN g.g_start AND g.g_end;

3) Outer Join
Ex4 t_student, t_professor 테이블을 join해서 학생이름과 지도교수 이름을 출력하라
(단! 지도 학생이 결정되지 않은 교수 명단, 지도교수가 결정되지 않은 학생명단 모두 출력)
-- ANSI 방식 --
= SELECT s.name, p.name
FROM t_student s FULL OUTER JOIN t_professor p
ON s.profno = p.profno;

4) Self Join : 원하는 데이터가 하나의 테이블에 다 들어있을 때
Ex5 t_dept2 테이블에서 부서명과 그 부서의 상위부서명을 출력하라
-- Oracle 방식 --
= SELECT d1.dname 부서명, d2.dname 상위부서명
FROM t_dept2 d1, t_dept2 d2
WHERE d1.pdept = d2.dcode;
-- ANSI 방식 --
= SELECT d1.dname 부서명, d2.dname 상위부서명
FROM t_dept2 d1 JOIN t_dept2 d2
ON d1.pdept = d2.dcode;

* 단, ORCLE DBMS에서의 JOIN을 나타내는 표현은 다음과 같다
- INNER JOIN >> JOIN
- LEFT OUTER JOIN >> LEFT JOIN
- RIGHT OUTER JOIN >> RIGHT JOIN
- CROSS JOIN
'SQL > Oracle' 카테고리의 다른 글
13_SQL VIEW의 사용 (0) | 2019.09.30 |
---|---|
12_SQL 서브 쿼리(Sub Query)문 (0) | 2019.09.27 |
10_SQL함수(6) 그룹함수 (0) | 2019.09.24 |
09_SQL함수(5) 단일행함수: 날짜함수 (0) | 2019.09.22 |
08_SQL함수(3) 단일행함수: 형변환함수 (0) | 2019.09.22 |
JOIN 이란?
- 한개가 아니라, 여러개의 테이블에서 정보를 가져와서 결과를 만들어 주는 기법
- 관계형 데이터베이스 (RDBMS) 의 가장 핵심 기술중 하나
- 표준화된 ANSI형 JOIN 방식이 있고, 각각의 DBMS마다 다른 사용방식이 있으나
본문에서는 ANSI와 ORCLE만 다룬다.

JOIN의 종류
여러개의 테이블 중 어떤 테이블을 기준으로 데이터를 가져올것인지에 따라 JOIN의 이름이 다르다.
다음 (1)~(5)를 먼저 보고 (6)을 보자.
(1) Inner Join
: 테이블 간의 공통 요소 (교집합)

(2) Left Join
: 왼쪽 테이블의 데이터 + 테이블 간의 공통 요소

(3) Right Join
: 오른쪽 테이블의 데이터 +테이블 간의 공통 요소

(4) Full Join
: 테이블들의 모든 요소

(5) Cross Join
: 테이블간의 결합에 있어서 모든 가능한 경우의 수의 데이터를 나열

위의 JOIN들은 Join에 참여하는 테이블에 값이 있을 경우에만 결과값을 얻는다.
이를 큰 개념에서 Inner Join이라고 한다.
그런데 만약 임의의 테이블인 A와 B테이블을 Join해서 (A U B)의 모든 필드를 얻으려고 할 때,
B테이블의 특정 필드가 null값을 포함해서 비어있다면,
(1)~(5)의 방식으로는 A와 B의 온전한 Join 결과를 얻을 수 없다.
따라서 레코드가 부분적으로 null값을 포함하더라도,
null값은 null값인대로 출력할 수 있어야하고 이를 수행하는 Join문이 바로 Outer Join문이다.
(6) Outer Join
: 한쪽 테이블에 데이터가 있고 한쪽테이블에 없는 경우 데이터가 있는 쪽 테이블의 내용을 전부 출력
Outer Join에는 Left Outer Join, Right Outer Join, Full Outer Join 등이 있다.

JOIN의 사용
1) Equi Join (등가 Join) : Join의 결과가 특정 조건값과 '일치' 할 때
Ex1 t_student 테이블과 t_department 테이블을 사용하여 학생이름(name), 1전공 학과번호(deptno1),
1전공 학과 이름(dname) 을 출력하라
-- Oracle 방식 --
= SELECT s.name "학생이름", s.deptno1 "학과번호", d.dname "학과이름"
FROM t_student s, t_department d WHERE s.deptno1 = d.deptno;
-- ANSI 방식 --
= SELECT s.name "학생이름", s.deptno1 "학과번호", d.dname "학과이름"
FROM t_student s JOIN t_department d ON s.deptno1 = d.deptno;

1 >>> JOIN은 두개 이상의 테이블이 필연적으로 쿼리문에 등장하므로, 테이블에 대한 별칭을 사용해서
쿼리문 내에서 사용되는 필드가 어떤 테이블의 소속인지 알려줄 필요가 있다.
FROM t_student s, t_department d WHERE s.deptno1 = d.deptno;
2 >>> DBMS마다 쿼리문을 작성하는 방식의 차이가 있다. 앞에서 언급했듯 본문에서는 ANSI와 ORCLE만 다룬다.
Ex2 t_student 테이블, t_department 테이블, t_professor 테이블 을 join하여
‘학생이름(name)’, ‘학과이름(dname)’, ‘지도교수이름(name)’ 을 출력하라
-- Oracle 방식 --
= SELECT s.name "학생이름", d.name "학과이름" p.name "교수이름"
FROM t_student s, t_department d, t_professor p
WHERE s.deptno1 = d.deptno AND s.profno = p.profno;
-- ANSI 방식 --
= SELECT s.name "학생이름", d.name "학과이름" p.name "교수이름"
FROM t_student s
JOIN t_department d
ON s.deptno1 = d.deptno
JOIN t_professor p
ON s.profno = p.profno;

2) Non Equi Join (비등가 Join) : Join의 결과가 특정 조건 범위에 내에 존재할 때


Ex3 t_customer 테이블, t_gift 테이블이 위와 같을 때 join하여 고객의 마일리지 포인트별로
받을수 있는 상품을 조회하고 고객의 '이름(c_name)'과 포인트(c_point) 상품명(g_name)을 출력하라
(단, t_gift 테이블의 g_start와 g_end는 포인트범위의 시작과 끝을 나타내고 있다)
-- Oracle 방식 --
= SELECT c.c_name "고객명", c.c_point "포인트", g.g_name "상품명"
FROM t_customer c, t_gift g
WHERE c.c_point BETWEEN g.g_start AND g.g_end;
-- 고객의 포인트값이 기프트의 상한선과 하한선 포인트 사이에 존재해야하므로 BETWEEN~IN사용
-- ANSI 방식 --
= SELECT c.c_name "고객명", c.c_point "포인트", g.g_name "상품명"
FROM t_customer c JOIN t_gift g
ON c.c_point BETWEEN g.g_start AND g.g_end;

3) Outer Join
Ex4 t_student, t_professor 테이블을 join해서 학생이름과 지도교수 이름을 출력하라
(단! 지도 학생이 결정되지 않은 교수 명단, 지도교수가 결정되지 않은 학생명단 모두 출력)
-- ANSI 방식 --
= SELECT s.name, p.name
FROM t_student s FULL OUTER JOIN t_professor p
ON s.profno = p.profno;

4) Self Join : 원하는 데이터가 하나의 테이블에 다 들어있을 때
Ex5 t_dept2 테이블에서 부서명과 그 부서의 상위부서명을 출력하라
-- Oracle 방식 --
= SELECT d1.dname 부서명, d2.dname 상위부서명
FROM t_dept2 d1, t_dept2 d2
WHERE d1.pdept = d2.dcode;
-- ANSI 방식 --
= SELECT d1.dname 부서명, d2.dname 상위부서명
FROM t_dept2 d1 JOIN t_dept2 d2
ON d1.pdept = d2.dcode;

* 단, ORCLE DBMS에서의 JOIN을 나타내는 표현은 다음과 같다
- INNER JOIN >> JOIN
- LEFT OUTER JOIN >> LEFT JOIN
- RIGHT OUTER JOIN >> RIGHT JOIN
- CROSS JOIN
'SQL > Oracle' 카테고리의 다른 글
13_SQL VIEW의 사용 (0) | 2019.09.30 |
---|---|
12_SQL 서브 쿼리(Sub Query)문 (0) | 2019.09.27 |
10_SQL함수(6) 그룹함수 (0) | 2019.09.24 |
09_SQL함수(5) 단일행함수: 날짜함수 (0) | 2019.09.22 |
08_SQL함수(3) 단일행함수: 형변환함수 (0) | 2019.09.22 |