코딩 개발/ORACLE

ORACLE - JOIN (ANSI SQL, ORACLE JOIN, INNER JOIN, OUTER JOIN)

호소세 2023. 5. 11. 22:12
728x90
반응형

https://pabeba.tistory.com/143

 

ORACLE - Foreign Key 제약

https://pabeba.tistory.com/137 DB 정규화 정규화 이상현상이 있는 관계를 분해하여 이상현상을 없애는 과정입니다. 이상현상이 존재하는 관계를 분해하여 여러개의 table을 생성합니다. 이를 단계별로

pabeba.tistory.com

JOIN은 Foreign Key 제약이 걸린 자식테이블과 부모 테이블을 합치는 행위라고 생각합니다.

JOIN SQL란?

여러 테이블의 정보를 결합해 조회하기 위한 SQL입니다. 

JOIN에는 크게 INNER JOIN, OUTER JOIN이 있습니다.

 

테이블을 어떻게 합치는지 알아볼까요?

 

예제

CREATE TABLE k_department(
	deptno NUMBER PRIMARY KEY,
	dname VARCHAR2(100) NOT NULL,
	loc VARCHAR2(100) NOT NULL,
	tel VARCHAR2(100) NOT NULL
)
-- 자식 테이블 : 참조하는 테이블 
CREATE TABLE k_employee(
	empno NUMBER PRIMARY KEY,
	ename VARCHAR2(100) NOT NULL,
	sal NUMBER NOT NULL,
	job VARCHAR2(100) NOT NULL,
	deptno NUMBER NOT NULL,
	CONSTRAINT fk_k_emp FOREIGN KEY(deptno) REFERENCES k_department(deptno)
)
INSERT INTO k_employee(empno,ename,sal,job,deptno) VALUES(1,'아이유',200,'프로그래머',10);
INSERT INTO k_employee(empno,ename,sal,job,deptno) VALUES(2,'손흥민',800,'프로그래머',10);
INSERT INTO k_employee(empno,ename,sal,job,deptno) VALUES(3,'이강인',400,'프로그래머',10);
INSERT INTO k_employee(empno,ename,sal,job,deptno) VALUES(4,'황희찬',600,'기획',30);
INSERT INTO k_employee(empno,ename,sal,job,deptno) VALUES(5,'이재성',900,'프로그래머',20);

INSERT INTO k_department(deptno,dname,loc,tel) VALUES(10,'연구개발','판교','031');
INSERT INTO k_department(deptno,dname,loc,tel) VALUES(20,'공공사업','종로','02');
INSERT INTO k_department(deptno,dname,loc,tel) VALUES(30,'전략기획','오리','032');

deptno 라는 Column으로 연결된 두 테이블을 join 문을 이용하여 합쳐보겠습니다.

 

예시1. INNER JOIN을 이용하여 테이블 합치기

1. ANSI 버전

SELECT	e.ename,e.sal,e.job,d.dname,d.loc
FROM	k_employee e
INNER JOIN  k_department d  ON e.deptno=d.deptno

테이블 간의 상응(매칭)하는 컬럼 정보가 존재할 때 조회합니다. 교집합을 나타냅니다.

문장을 보시면 employee 테이블에 department 테이블을 붙이는데 교집합인 것을 붙이는 inner join을 사용하고 있습니다.

부서번호 10, 20, 30 에 대한 데이터만 옆에 붙고 40에 대한 정보는 없으니까 아예 데이터로 나오지 않을 것입니다.

결과 값을 보실까요?

deptno에 해당하는 값이 있으면 옆에 붙어서 부서의 정보들을 전달해줍니다.

 

2. ORACLE 버전

oracle 버전 join이 있다는 것이 신기합니다.

SELECT	e.ename,e.sal,e.job,e.deptno,d.dname,d.loc,d.tel
FROM	k_employee e, k_department d
WHERE e.deptno=d.deptno

두 테이블을 선택해서(곱집합 테이블 생성) where 문으로 공통된 부분만 찾아오라는 조건절을 사용하여 inner join을 실행합니다.

 

 

예시2. OUTER JOIN 이용하여 테이블 붙이기

테이블 간의 상응하는 컬럼의 정보가 존재하지 않을 때에도 조회, 여러 테이블 중 한 쪽에서 데이터가 있고, 다른 한쪽에는 데이터가 없는 경우 데이터가 있는 쪽의 내용을 모두 조회합니다.

 

OUTER JOIN에는 LEFT JOIN과 RIGHT JOIN이 있습니다.

 

LEFT JOIN 

LEFT JOIN은 말 그대로 왼쪽 테이블의 기준으로 오른쪽 테이블의 정보를 결합하는 명령어 입니다.

왼쪽 테이블의 모든 데이터를 포함하면서 오른쪽 테이블의 데이터를 결합하는 방식입니다.

SELECT	d.deptno,d.dname,d.loce.ename,e.sal,e.job
FROM	k_department d
LEFT OUTER JOIN k_employee e   ON e.deptno=d.deptno

department 테이블을 기준으로 employee 테이블을 붙이면 어떠한 일이 일어날까요?

employee 테이블에는 40번 부서의 사람이 없는데 데이터가 어떻게 나올까요?

보시면 아시겠지만 deptno 40 의 값은 department 테이블의 모든 값이 나와야하는 상황이어서 나왔지만 옆에 붙은 employee 테이블에는 40에 대한 값이 없기 때문에 NULL 값으로 처리가 되었습니다.

Right JOIN

SELECT	e.ename,e.sal,e.job,d.deptno,d.dname,d.loc
FROM	k_employee e
RIGHT OUTER JOIN  k_department d  ON e.deptno=d.deptno

이와 같이 right join도 옆에 붙이는 테이블 기준으로 표가 완성이 되기 때문에 FROM과 JOIN 하는 테이블의 순서를 바꿔서 sql문을 작성하면 같은 결과가 나오게 됩니다.

 

소감

테이블이 점점 많아지면 붙여야 할 테이블도 많아져서 join 지옥에 시달릴 것 같습니다. 하지만 기본 원리만 잘 알고 있다면 언제든지 응용할 수 있는 그런 수준이라고 생각합니다. 그냥 기준 테이블 옆에 새로운 테이블을 공통적인 부분으로 붙인다는 생각을 하면 가장 쉽더라고요. 이해가 잘 안된다면 손으로 테이블을 두개 그려서 붙여보는 연습을 해도 좋은 것 같습니다.


출처

https://hongong.hanbit.co.kr/sql-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-joininner-outer-cross-self-join/

반응형