Practice makes perfect

[DataBase] 조인(JOIN) 본문

빅데이터/DataBase

[DataBase] 조인(JOIN)

kerpect 2020. 4. 12. 17:17

JOIN? 두 개 이상의 테이블에 나뉘어져 있는 데이터를 한 번의 SQL 문으로 원하는 결과를 얻을 수 있는 기능입니다.

좀 더 효율적으로 빠르게 하기 위해서 JOIN 을 통해서 나뉘어진 테이블의 결과 중 원하는 것만 가져올 때 사용합니다.

       종류                                      내용
     cross join

2개 이상의 테이블이 조인될 때 where절에 의해 공통되는 컬럼에 의한 결합이 발생

하지 않는 경우를 의미합니다.

     equi join 

조인 대상이 되는 두 테이블에서 공통적으로 존재하는 컬럼의 값이 일치되는 행을

연결하여 결과를 생성하는 방법입니다.

  non-equi join 

동일 컬럼이 없이 다른 조건을 사용하여 join 조건에 특정 범위 내에 있는지를 조사

하기 위해서 조건절에 조인 조건을 = 연산자 이외의 비교 연산자를 이용합니다.

      self join 

하나의 테이블 내에서, 자기 자신과 조인을 통해 원하는 자료를 얻는 방법입니다.

     outer join 

조인 조건에 만족하지 못해서 해당 결과를 출력시에 누락이 되는 문제점이 발생된다.

해당 레코드(row)를 출력하고 싶을 때 사용하는 join 방법입니다.

 

지금부터 각 조건들의 특징과 사용방법을 예시들을 통해서 설명하겠습니다.

 

1) cross join : 2개 이상의 테이블이 조인될 때  where절에 의해 공통되는 칼럼에 의한 결합이 발생하지 않는 경우

-- 공통이 되어지는 컬럼의 이름 가지고 결함됩니다.  

 

형태 : select * from 필드명1, 필드명2;

select * from emp, dept; 
-- 하나가 아닌 2개의 테이블을 지정 (dept 4 + mep 14 = 총 56/ 단순결합) 
직관적이지 않으므로 많이 사용하지 않습니다. 

 

 

2) equi join: 조인 대상이 되는 두 테이블에서 공통적으로 존재하는 컬럼의 값이 일치되는 행을 연결하여 결과를 생성하는 방법

-- 동일 칼럼을 기준으로 조인합니다.

 

형태 : select * from 테이블1, 테이블2 where 테이블1. 필드명 = 테이블2. 필드명;  (필드명은 같은 것을 사용)  

select * from emp, dept where emp. deptno = dept.deptno; 
-- 같은 데이터를 하나로 결합하여 출력.(dept 4 equi join mep 14 = 총 14) 
-- 조건에 만족하는 내용을 선별하는 것이다. 

 

※ 컬럼명 앞에다가 테이블명을 기술하여 컬럼 소속을 명확히 밝힐 수 있습니다.

select emp.ename, dept.dname, dept.loc, emp. deptno  
from emp, dept
where emp.deptno = dept.deptno
and ename = 'SCOTT';

※ 테이블 옆에 별칭을 부여할 때는 별칭으로 사용할 수 있습니다. (테이블 이름이 길때 유용하게 많이 사용합니다.)

select e.ename, d.dname, d.loc, e. deptno  
from emp e , dept d 
where e.deptno = d.deptno 
and e.ename = 'SCOTT;

-- 테이블 이름에 별칭을 붙일 때는 as 를 붙이지 않습니다. 
-- 별칭을 붙였을 때는 별칭으로만 사용해야하며, 테이블명을 사용하면 안됩니다.

 

 

3) non-equi join: 동일 컬럼이 없이 다른 조건을 사용하여 join 조인 조건에 특정 범위 내에 있는지를 조사하기 위해서
조건절에 조인 조건을 = 연산자 이외의 비교 연산자를 이용/ 동일 칼럼이 없이 다른 조건을 사용하여 조인

 

1) 연산자 활용
select ename, sal, grade from emp, salgrade  
where sal>= losal and sal <= hisal;

2) between 활용 (between A and B)
select ename, sal, grade from emp, salgrade  
where sal between losal and hisal ;

위의 내용을 자세하게 설명하겠습니다. 
select  ename, sal, grade, dname -- 겹치는 것이 없기 때문에 따로 별칭을 붙일 필요가 없다. 
from emp, dept, salgrade -- 테이블 이름 / 이대로 출력 하면 (14*5*4가 추력된다)
where emp. deptno = dept. deptno  -- equi join / 이대로 출력하면 (14 항목)
and  sal between losal and hisal ; -- 정보를 추가 / 14항목 출력!

 

 

4) self join:  하나의 테이블 내에서, 자기 자신과 조인을 통해 원하는 자료를 얻는 방법

-- 한 테이블 내에서 조인합니다.

(mgr : 사수번호/ empno : 사원번호 )/ 같은 테이블 안에서 데이터를 정보를 얻습니다. 

select employee.ename, employee.mgr , manager.ename
from emp employee, emp manager -- 하나의 테이블을 두개의 테이블 인거 처럼 별칭을 이용하여 사용
where employee. mgr = manager. empno; -- 결과 13개 / 사장은 사수가 없기 때문에 나오지 않습니다. 

 

 

(5)outer join: 조인 조건에 만족하지 못해서 해당 결과를 출력시에 누락이 되는 문제점이 발생된다. 해당 레코드(row)를
출럭하고 싶을 때 사용하는 join 방법

-- 조인 조건에 만족하지 않는 행도 나타낸다.

 

select  employee. ename, employee. mgr, manager. ename 
from emp employee,  emp manager
where employee. mgr =  manager. empno(+) ; -- = 을 기준으로 값을 출력하고 싶지 않은 쪽에 (+)을 붙입니다.  

 

 

 

★ ANSI 조인 : 데이터베이스 회사들이 모두 이 기능을 구현해 놓았습니다. ( 표준 )

 

1) Ansi Cross join = oracle (cross join)

 

● Ansi Cross join
select * from emp cross join dept;

● oracle cross join
select * from emp, dept; 

 

 

2) Ansi Inner join  = oracle (Equi join)

①

● Ansi Inner join 
select ename, dname, emp. deptno
from emp inner join dept 
on emp. deptno = dept. deptno; 

● Ansi Inner join 
select ename, dname, deptno
from emp inner join dept 
using (deptno);

● oracle Equi Join
select ename, dname , emp. deptno
from emp , dept 
where emp. deptno = dept. deptno;

②

● Ansi Inner join 
select ename, dname, emp. deptno
from emp inner join dept 
on emp. deptno = dept. deptno
where ename = 'SCOTT';

● oracle Equi Join
select ename, dname , emp. deptno
from emp , dept 
where emp. deptno = dept. deptno
and ename = 'SCOTT';

 

 

3) natural join 

select ename, dname from emp natural join dept; 
-- 두 테이블에서 공통이 되는 컬럼 항목을 찾아서 공통이 되어지는 결과를 출력해줍니다.

 

 

4) Ansi Outer join = oracle(outer join)

● Ansi Outer join

select * from dept10 left outer join  dept11 
on dept10.deptno = dept11.deptno;  -- left는 왼쪽 값의 데이터 dept10 를 추가적으로 출력해준다. 

select * from dept10 right outer join dept11
on dept10.deptno = dept11.deptno;  -- right는 오른쪽 값의 데이터 dept11를 추가적으로 출력해준다. 

select * from dept10 full outer join dept11
on dept10.deptno = dept11.deptno; -- 모든 데이터의 값을 출력해준다. 

● oracle outer join
select * from dept10, dept11 
where dept10.deptno = dept11. deptno(+);
-- 플러스는 dept11(30.영업부)의 내용이 나올주 알았는데, 결과값은 (20,연구부)가 출력

select * from dept10, dept11 
where dept10.deptno(+) = dept11. deptno; 
-- 플러스는 dept10(20, 연구부)의 내용이 나올주 알았는데, 결과값은 (30,영업부)가 출력

select * from dept10, dept11 
where dept10.deptno(+) = dept11. deptno(+);
-- 양쪽의 더하기를 넣어서 모두 출력하고 싶지만 오라클은 지원해 주지 않습니다.(ERROR)