본문 바로가기

DB/오라클

오라클 조인 ( join )

# JOIN




#  JOIN ( INNER JOIN과 OUTER JOIN으로 구분됨 ) ( 아래가 ANSI표준쿼리  ) ( ()는 생략가능 )
JOIN -    INNER JOIN    -    EQUI JOIN    (    =    )
                        -    NON EQUI JOIN    (    >, >= , < )

     -    OUTER JOIN    -    LEFT (OUTER) JOIN
                        -    RIGHT(OUTER) JOIN
                        -    FULL(OUTER) JOIN

만약 INNER JOIN에서 한가지 문제점이 조인을 생성하려는 두 테이블의 두 컬럼에서 공통된
값이 없다면 데이터를 반환하지 못한다.
이때 사용하는것이 OUTER JOIN이다. 

(INNER) JOIN                -    둘다 일치하는 부분의 레코드를 반환
LEFT (OUTER) JOIN       -    LEFT테이블의 모든것과 RIGHT중 LEFT과 일치하는부분의 레코드를 반환
RIGHT (OUTER) JOIN     -    위반대
FULL (OUTER) JOIN       -    양쪽테이블 모든 부분을 반환    









# 먼저 아래 쿼리를 보자
    C가 100개 O가 50개의 레코드를 가지고있다면
    아래는 100*50개의 결과레코드를 출력하고 컬럼명은 두개 테이블 모두표시됨
SELECT *
FROM CUSTOMERS C, ORDERS O

하지만 우리가 원하는 결과는 두 테이블의 연관성있는 부분을 연결고리로 잡고 하나의 테이블로 
보기위함이다.
따라서 조건을 준다.
SELECT *
FROM CUSTOMERS C, ORDERS O
WHERE C.CUSTOMERID = O.CUSTOMERID


#simple join( 두테이블에 교집합 )( INNER JOIN과 동일 )
-->두개 이상의 관련 테이블로 부터 데이터를 출력하기위한 질의
-->from절에 join할 테이블을 명시하고 where절에 조인 조건을 작성
select
     e.empno, e.ename, e.deptno, d.dname
from emp e, dept d            ----emp는e  dept는d 라고 정의(가독성, 간결화)
where e.deptno=d.deptno
만약 SELECT * 로 할경우 e.deptno와 d.deptno 두 컬럼 생기는데 이때 는 두 컬럼 값이 모두 같다. 
 ( 조인 조건절에 의해 )


예제)위 로직에서 30번 부서만 따로 출력하시오...
select e.empno, e.ename, e.deptno, d.dname
from emp e, dept d
WHERE E.DEPTNO = D.DEPTNO
     AND E.DEPTNO = 30;

**다른 표기방법( from절에서 join... 이게 국제규격인가 그럴거임? )
SELECT
       E.EMPNO, E.ENAME, E.DEPTNO, D.DNAME
FROM EMP E INNER JOIN DEPT D ON E.DEPTNO = D.DEPTNO
WHERE E.DEPTNO = 30;


# INNER JOIN중 Non-Equi조인
               한테이블의 어떤 컬럼도 조인할 테이블의 컬럼에 직접적으로 일치하지않을때 사용
               연산자는 = 이외의 <= , >=, <> , Between And 연산자를 사용

SELECT E.ENAME, E.JOB, E.SAL , S.GRADE
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL
(EMP)     (      SALGRADE     )
2000      1500~2200     A등급
2420       2200~2600    B등급
2500       2200~2600    B등급
2700       2600~3000    C등급
     
( 참고로 NON-EQUI조인도 OUTER조인되네... E.SAL(+) 쪽 아니면 S.LOSAL(+) S.HISAL(+)       )




# 3개 이상의 조인
1. ORACLE( 3개 테이블을 한번에 놓고 JOIN하면됨 )
SELECT *
FROM MEMBER M , DEPT D, EMP E 
WHERE M.DEPT_ID = D.DEPT_ID
        AND M.MEM_ID = E.MEM_ID
2. ANSI표준쿼리( 연속해서 새로운 테이블 JOIN하면됨 )
SELECT *
FROM MEMBER M JOIN DEPT D ON M.DEPT_ID = D.DEPT_ID
    JOIN EMP E ON M.MEM_ID = E.MEM_ID


# outer 조인( 오라클은 외부조인연산자 (+) 를 지원함 )


위 3개 테이블 다 조인시 
SELECT *
FROM MEM M , DEPT D , MEM_LOG L
WHERE M.DEPT_ID = D.DEPT_ID
       AND M.MEM_ID = L.MEM_ID
1    갓대희    aa44@a232323a    10    10    기술개발실    1    2018-12-20 17:33:59
1    갓대희    aa44@a232323a    10    10    기술개발실    1    2018-12-20 17:34:08
2    갓동수    aa44@a232323223a    10    10    기술개발실    2    2018-12-20 17:34:12

조인중 사자의 정보를 보고싶으면
위 쿼리문에 다음을 추가
    AND M.MEM_ID = 0001
하지만 결과는 ROW가 없다. 이유는 3개 공통부분에서 사자의 아이디인 0001의 LOG테이블부분이
없기 때문이다.

하지만 사자의 LOG기록이 없더라도 사자의 다른 기본정보는 보고싶다.
( 3개 조인하는데 공통부분이 없더라도 그부분을 NULL값으로 해서 JOIN하고싶다면 그 테이블에 
    (+)를 붙히면 된다 )

SELECT *
FROM MEM M , DEPT D , MEM_LOG L
WHERE M.DEPT_ID = D.DEPT_ID
       AND M.MEM_ID = L.MEM_ID(+)----> 이부분이 없더라도 NULL로해서 조인하여 다른 조인에 
                                       의해 결과행은 보여진다.
1    갓대희  10    10    aa44@a232323a    기술개발실    1    2018-12-20 17:33:59
1    갓대희  10    10    aa44@a232323a    기술개발실    1    2018-12-20 17:34:08
2    갓동수  10    10    aa44@a232323223a 기술개발실    2    2018-12-20 17:34:12
3    사자    20    20    aa424@a232323223a 경영개발실   NULL    NULL   

간단히 말하여 데이터가 없을 수도 있는쪽 JOIN컬럼에(+) 추가하여
 OUTER JOIN가능
( (+)반대쪽의 테이블이 전부 표시된다 )


이는 ANSI표준쿼리에서는 다음과같다

오라클의 (+)붙은 테이블이 NULL로 해서 나옴( (+)반대쪽이 풀로 나옴 )
SELECT *
FROM MEM M , DEPT D , MEM_LOG L
WHERE M.DEPT_ID = D.DEPT_ID
       AND M.MEM_ID = L.MEM_ID(+)
LEFT JOIN의 왼쪽 테이블이 풀로 나옴
SELECT *
FROM MEM M INNER JOIN DEPT D ON M.DEPT_ID = D.DEPT_ID
       LEFT JOIN MEM_LOG L ON M.MEM_ID = L.MEM_ID
반대네.... 두방식 표시하는 방향이....




같은 값 끼리 조인시 null값은 버려진다
이럴때 버려진 값도 null행을하나만들어서 조인해서 같이 구해오는 조인방법
select  e.id  ,e.last_name ,c.name
from   s_emp e left outer join s_customer c----> left테이블은 풀로 나오게
on c.sales_rep_id=e.id

다른방법(같은해석)
select e.id, e.last_name, c.name
from s_emp e, s_customer c
where e.id=c.sales_rep_id(+);--->조인되는 값이 없는 조인쪽에 (+)를 위치 시킨다.
                             --->(+)반대편이 풀로 나옴





'DB > 오라클' 카테고리의 다른 글

오라클 집합 연산자( union, intersect, minus )  (0) 2019.04.03
오라클 관계  (0) 2019.04.03
오라클 서브쿼리 ( subquery )  (0) 2019.04.03
오라클 함수  (0) 2019.04.03
계층형 쿼리  (0) 2019.04.03