상세 컨텐츠

본문 제목

JOIN (Oracle JOIN, ANSI JOIN, INNER JOIN, OUTER JOIN, SELF JOIN)

DataBase/Oracle

by H_Develop 2022. 6. 8. 22:11

본문

조인이 필요할 때에는 먼저

1) 필요한, COLUMN_NAME, RECORD 확인

2) COLUMN_NAME 과 RECORD 를 가지고 있는 TABLE_NAME 확인

3) DESC TABLE 로 공통적으로 가지고 있는 COLUMN_NAME 을 확인

( 관계형 데이터베이스이기 때문에 각 테이블은 특정 항목에서 PK와 FK의 관계가 적어도 하나씩은 있다

 보통 CREATE TABLE 시, JOIN 할 COLUMN을 FOREIGN KEY 로 지정해둔다) 

4) INNER JOIN, SELF JOIN, FULL JOIN 등 여러 형태의 JOIN으로 원하는 값을 출력하면 된다.

 

JOIN 명령어를 사용하지 않고, 여러 TABLE을 combined (ORACLE JOIN)

select last_name, employee_id, department_name 
FROM EMPLOYEES, DEPARTMNETS
where last_name = 'King'
// FROM 불러오는 것을 EMPLOYEES 와 DEPARTMENTS 에서 불러옴으로 써,
// SELECT 문에서 EMPLOYEES_TABLE 에만 있는 LAST_NAME, 
// DEPARTMENTS_TABLE 에만 있는 DEPARTMENT_NAME 을 출력할 수 있다.

select last_name, employee_id, department_name 
from employees, departments
where last_name = 'King'
and employees.department_id = departments.department_id
// employees table의 department_id 와 departments table의 department_id 가 같은 값에서
// last_name 이 'King' 값만 출력한다.

select e.last_name, e.employee_id, d.department_name 
from employees e, departments d
where last_name = 'King'
and e.department_id = d.department_id
// from employees e, departments d 으로 별명을 만들어 사용. Alias, Cname(Canonical) name

3개 table JOIN

SELECT last_name, salary, employee_id, job_title, department_name
FROM EMPLOYEES e, JOBS j, DEPARTMENTS d
WHERE e.job_id = j.job_id AND e.department_id = d.department_id
and last_name = 'King'

// implicity 암묵적으로 / explicity 표면적으로, 명시적으로 

 

JOIN 명령어를 사용 (ANSI JOIN)

select e.last_name, e.employee_id, d.department_name, d.department_id
from employees e INNER JOIN departments d
ON e.department_id = d.department_id
where last_name = 'King'
// from에서 employees 와 departments를 join 해주고,
// on에서 employees_table 과 department_table 의 동일한 column을 
// e.department_id = d.department_id 으로 지정

3개 table JOIN

select last_name, salary, employee_id, job_title, department_name
from employees e 	JOIN jobs j 			ON e.job_id = j.job_id
                 	JOIN departments d 		ON e.department_id = d.department_id
where last_name = 'King'
// employees_table과 jobs_table, employees_table과 departments_table가 공통 column이 있기에,
// from 다음 employees 를 먼저 쓰고, 다음에 JOIN해줄 table_name을 작성.
// 2개 TABLE을 JOIN할 때 처럼 JOIN과 ON 모두 작성해주고, 
// 3개 이상은 추가적으로 JOIN과 ON을 모두 작성해주며 코드를 늘려준다.

 

proprietary 종속적인
하나의 제품, 브랜드만 고집하는 것은 좋지 않음.

 

OUTER JOIN

 

//				*** 필요한 상황 ***
select employee_id, last_name, to_char(hire_date, 'yyyy/mm'), department_name
from employees
where to_char(hire_date, 'yyyy/mm') between '1999/01' and '1999/06'
// 입사일, 1999.01 ~ 1999.06 직원들 11명이 나옴
select employee_id, last_name, to_char(hire_date, 'yyyy/mm'), department_name
from employees JOIN departments ON employees.department_id = departments.department_id
where to_char(hire_date, 'yyyy/mm') between '1999/01' and '1999/06'
// 10명이 나옴. 제외 된 1명은 last_name = Grant, employee_id = '178' 
// 부서배치를 받지 못한 신입사원(예를들어.), department_id 를 부여받지 못함.
// 이런 상황에서 사용하는 조인이 outer join

// JOIN 문에서 데이터가 많은 employees 테이블을 
// 왼쪽에 두면, LEFT OUTER JOIN
// 오른쪽에 두면, RIGHT OUTER JOIN 을 사용

//			*** OUTER JOIN 사용 ***
select employee_id, last_name, to_char(hire_date, 'yyyy-mm'), department_name
from EMPLOYEES e LEFT OUTER JOIN DEPARTMENTS d
 on  d.department_id = e.department_id
where to_char(hire_date, 'yyyy-mm') between '1999-01' and '1999-06'
// 동일함, 위 LEFT 사용, 아래 RIGHT 사용
select employee_id, last_name, to_char(hire_date, 'yyyy-mm'), department_name
from DEPARTMENTS d RIGHT OUTER JOIN EMPLOYEES e
 on  d.department_id = e.department_id
where to_char(hire_date, 'yyyy-mm') between '1999-01' and '1999-06'

select employee_id, last_name, to_char(hire_date, 'yyyy-mm'), department_name
from employees e JOIN departments d
 on d.department_id(+) = e.department_id
where to_char(hire_date, 'yyyy-mm') between '1999-01' and '1999-06'
// OUTER JOIN을 사용하지않고, INNER JOIN을 사용하며, 
// ON 뒤에 데이터가 부족한 쪽에 d.department_id(+)를 작성하여 보충해준다.

 

SELF JOIN

select last_name, d.manager_id, employee_id
from   employees e JOIN departments d
ON     d.department_id = e.department_id
WHERE d.department_name = 'Executive'
// 일반적인 INNER JOIN 으로 해당 직원의 매니저 이름을 같이 출력할 수 없다.

select A.last_name as EMP_NAME, B.last_name as MGR_NAME
from employees A JOIN employees B   on A.manager_id = B.employee_id 
                 JOIN departments D on A.department_id = D.department_id
where D.department_name = 'Executive' =>상사가 last_name으로 보임;
// 같은 employees_table을 A와 B, 두개로 만들고,
// A.last_name 은 직원 이름을 출력, B.last_name은 A.last_name 직원 MANAGER의 last_name을 출력
// on A.manager_id = B.employee_id으로 직원의 MANAGER 의 이름을 찾을 수 있게 한다.
// on A.department_id = D.department_id 이것은 부서이름, Executive를 찾기 위함.

EMP_NAME	MGR_NAME
De Haan		King
Kochhar		King

select employee_id, last_name, manager_id 
from employees
WHERE d.department_name = 'Executive'
이렇게 하면, where 문 검색이 안됨 !

 

DEPARTMENTS_TABLE의 Executive 부서의 부서장과 부서원 이름을 보이시오.

 

select department_name, e.last_name "EMP_NAME", f.last_name "MNG_NAME"
from employees e JOIN employees f 	ON e.manager_id = f.employee_id
				 JOIN departments d ON e.department_id = d.department_id
where department_name = 'Executive'
// Alias JOIN

select department_name, a.last_name, b.last_name
from employees a, employees b, departments c
where a.manager_id 		 = b.employee_id
and   a.department_id	 = c.department_id
and   c.department_name  = 'Executive'
// Oracle JOIN
// 예를들어 매니저의 이름을 구하기위해,
// employees_table에는 last_name 과 manager_id 가 있으니, 사원 last_name은 바로 찾을 수 있고, 
// manager_id를 employee_id와 연결해줌으로써, manager의 last_name을 찾을 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

관련글 더보기