본문 바로가기

Data Science/SQLD

[SQLD] SQL 활용 2-1. 표준 조인

반응형

1. STANDARD SQL 개요

가. 일반 집합 연산자
나. 순수 관계 연산자

 

가. 일반 집합 연산자

 

1. UNION 연산          -> UNION 기능
2. INTERSECTION 연산 -> INTERSECTION 기능
3. DIFFERENCE 연산    -> EXCEPT(MINUS) 기능
4. PRODUCT 연산       -> CROSS JOIN 기능

 

1. UNION 연산 [UNION | UNION ALL]

-> 합집합 제공 

: 공통 교집합의 중복을 없애기 위한 작업 [정렬 작업 발생]

 

2. INTERECTION 연산 

-> 교집합

: 두 집합의 공통집합을 추출

 

3. DIFFERENCE 연산

-> 차집합

: 첫 번째 집합에서 두 번째 집합과의 공통 집합 제외한 부분 [EXCEPT / MINUS]

 

4. PRODUCT 연산

-> 곱집합

: JOIN 조건이 없는 경우 생길 수 있는 모든 데이터 조합

 


나. 순수 관계 연산자

5. SELECT 연산 -> WHERE 절
6. PROJECT 연산 -> SELECT 절
7. (NATURAL) JOIN 연산 -> 다양한 JOIN 기능
8. DIVIDE 연산은 사용하지 않음

 

5. SELECT 연산

-> WHERE 절의 조건절 기능

 

6. PROJECT 연산

-> SELECT 절의 칼럼 선택 기능

 

7. JOIN 연산

-> WEHRE 절의 JOIN 조건과 함께 FROM 절의

NATURAL JOIN

INNER JOIN

OUTER JOIN

USING 조건절

ON 조건절 등으로 발전

 

8. DIVIDE 연산

 

RDBMS의 경우 요구사항 분석, 개념적 데이터 모델링, 논리적 데이터 모델링, 물리적 데이터 모델링 단계를 거쳐

엔터티 확정정규화 과정, M:M (다대다) 관계를 분해하는 절차를 밟는다.

 

이 과정에서 특히 정규화 과정은 데이터 정합성 데이터 저장 공간의 절약을 위해 엔터티를 최대한 분리하는 작업

 

JOIN

-> 정규화 과정에서 하나의 주제에 관련 있는 엔터티가 여러 개로 나누어지는데 이렇게 흩어진 데이터를 연결해서 원하는 데이터를 가져오는 작업

 


2. FROM 절 JOIN 형태

INNER JOIN
NATURAL JOIN
USING 조건절
ON 조건절
CROSS JOIN
OUTER JOIN

WHERE절 JOIN과 FROM절 JOIN의 차이

: 추가된 선택 기능으로 테이블 간의 JOIN 조건을 FROM 절에서 명시적으로 정의 가능

 

1. INNER JOIN

: WHERE 절에서부터 사용하던 JOIN의 DEFAULT 옵션

 

-> JOIN 조건에서 동일한 값이 있는 행만 반환 [생략가능]

 

단, CROSS JOIN, OUTER JOIN과 사용 불가

 

2. NATURAL JOIN

: INNER JOIN의 하위 개념

-> 두 테이블 간의 동일한 이름을 갖는 모든 칼럼들에 대해 EQUI JOIN을 수행

 

ON 조건절

: WHERE 절에서 JOIN 조건과 용도가 불분명한 경우가 발생이 가능한데, FROM절의 ON 조건절로 분리 표시

-> 명시적으로 JOIN 조건을 구분가능, 칼럼명이 상호 다르더라도 JOIN 조건으로 사용 가능

 

3. INNER JOIN [WHERE 절에서 사용하던 JOIN 조건을 FROM 절에서 정의]

: 내부 조인으로 동일한 값이 있는 행만 반환

 

-> USING 조건절이나 ON 조건절 필수 사용

 

(1) 사원 번호와 사원 이름, 소속부서 코드와 소속부서 이름을 찾아본다.

WHERE 절 JOIN 조건
SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;

위 SQL과 아래 SQL은 같은 결과를 얻을 수 있다.

FROM 절 JOIN 조건 SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP INNER JOIN DEPT
ON EMP.DEPTNO = DEPT.DEPTNO;

INNER는 JOIN의 디폴트 옵션으로 아래 SQL문과 같이 생략 가능하다.
SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP JOIN DEPT
ON EMP.DEPTNO = DEPT.DEPTNO;

 

4. NATURAL JOIN

: 동일한 이름을 갖는 모든 칼럼들에 대해 EQUI JOIN 수행

 

단, USING 조건절, ON 조건절, WHERE 절과 사용 불가

 

(2) 사원 번호와 사원 이름, 소속부서 코드와 소속부서 이름을 찾아본다.

SELECT DEPTNO, EMPNO, ENAME, DNAME
FROM EMP NATURAL JOIN DEPT;

JOIN에 사용된 칼럼들은 같은 데이터 유형이어야 하며, ALIAS나 테이블 명과 같은 접두사를 붙일 수 없다.

 

SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP NATURAL JOIN DEPT;

ERROR: NATURAL JOIN에 사용된 열은 식별자를 가질 수 없음

-> 조인 테이블의 데이터 성격(도메인)과 칼럼명 등이 동일해야 한다.

 

(3) 아래 '*' 와일드카드처럼 별도의 칼럼 순서를 지정하지 않으면 NATURAL JOIN의 기준이 되는 칼럼들이 다른 칼럼보다 먼저 출력된다. (ex: DEPTNO가 첫 번째 칼럼이 된다.)

이때 NATURAL JOIN은 JOIN에 사용된 같은 이름의 칼럼을 하나로 처리

SELECT *
FROM EMP NATURAL JOIN DEPT;

 

(4) 반면, INNER JOIN의 경우 첫 번째 테이블, 두 번째 테이블의 칼럼 순서대로 데이터가 출력된다.

SELECT *
FROM EMP INNER JOIN DEPT
ON EMP.DEPTNO = DEPT.DEPTNO;

 

 

NATURAL JOIN은 JOIN에 사용된 같은 이름의 칼럼을 하나로 처리하지만, INNER JOIN은 별개의 칼럼 표시

 


(5)  NATURAL JOIN과 INNER JOIN의 차이를 자세히 설명하기 위해 DEPT_TEMP 테이블을 임시로 만든다. 

CREATE TABLE DEPT_TEMP
AS SELECT * FROM DEPT;

UPDATE DEPT_TEMP
SET DNAME = 'R&D'
WHERE DNAME = 'RESEARCH';

UPDATE DEPT_TEMP
SET DNAME = 'MARKETING'
WHERE DNAME = 'SALES';

SELECT * FROM DEPT_TEMP;


-> 부서번호 20과 30의 DNAME이 'R&D'와 'MARKETING'으로 변경된다.

 

(6) 세 개의 칼럼명이 모두 같은 DEPT와 DEPT_TEMP 테이블을 NATURAL [INNER] JOIN으로 수행한다. 

SELECT *
FROM DEPT NATURAL INNER JOIN DEPT_TEMP;

INNER는 DEFAULT 옵션으로 아래와 같이 생략 가능하므로 위 SQL과 아래 SQL은 같은 결과를 얻을 수 있다.
SELECT * FROM DEPT NATURAL JOIN DEPT_TEMP;

-> DNAME의 내용이 바뀐 부서번호 20, 30의 데이터는 실행 결과에서 제외

 

(7) 다음에는 같은 조건이지만 출력 칼럼에서 차이가 나는 일반적인 INNER JOIN을 수행한다.

SELECT *
FROM DEPT JOIN DEPT_TEMP
ON DEPT.DEPTNO = DEPT_TEMP.DEPTNO AND DEPT.DNAME = DEPT_TEMP.DNAME AND DEPT.LOC = DEPT_TEMP.LOC;

위 SQL과 아래 SQL은 같은 결과를 얻을 수 있다.

SELECT *
FROM DEPT, DEPT_TEMP
WHERE DEPT.DEPTNO = DEPT_TEMP.DEPTNO
AND DEPT.DNAME = DEPT_TEMP.DNAME
AND DEPT.LOC = DEPT_TEMP.LOC;

 

NATURAL JOIN은 JOIN에 사용된 같은 이름의 칼럼을 하나로 처리하지만,
INNER JOIN의 경우는 2개의 칼럼으로 표시

5. USING 조건절

: FROM 절의 USING 조건절을 이용하면 같은 이름을 가진 칼럼들 중에서 원하는 칼럼에 대해서만 선택적으로 EQUI JOIN을 할 수가 있다.

 

(8)세 개의 칼럼명이 모두 같은 DEPT와 DEPT_TEMP 테이블을 DEPTNO 칼럼을 이 용한 [INNER] JOIN의 USING 조건절로 수행한다.

SELECT *
FROM DEPT JOIN DEPT_TEMP
USING (DEPTNO);
별도의 칼럼 순서를 지정하지 않으면 USING 조건절의 기준 이 되는 칼럼이 다른 칼럼보다 먼저 출력
-> JOIN에 사용된 같은 이름의 칼럼을 하나로 처리

 

(9) USING 조건절을 이용한 EQUI JOIN에서도 NATURAL JOIN과 마찬가지로 JOIN 칼럼에 대해서는 ALIAS나 테이블 이름과 같은 접두사를 붙일 수 없다. (DEPT.DEPTNO → DEPTNO) 

주의
SELECT DEPT.DEPTNO, DEPT.DNAME, DEPT.LOC, DEPT_TEMP.DNAME, DEPT_TEMP.LOC
FROM DEPT JOIN DEPT_TEMP USING (DEPTNO);

ERROR: USING 절의 열 부분은 식별자를 가질 수 없음


SELECT DEPTNO, DEPT.DNAME, DEPT.LOC, DEPT_TEMP.DNAME, DEPT_TEMP.LOC
FROM DEPT JOIN DEPT_TEMP
USING (DEPTNO);

 

(10) 이번에는 DEPT와 DEPT_TEMP 테이블의 일부 데이터 내용이 변경되었던 DNAME 칼럼을 조인 조건으로 [INNER] JOIN의 USING 조건절을 수행한다.

SELECT *
FROM DEPT JOIN DEPT_TEMP
USING (DNAME);
DNAME의 내용이 바뀐 부서번호 20, 30의 경우는 결과에서 제외
USING에 사용된 DNAME이 첫 번째 칼럼으로 출력된 것과 함께,
JOIN 조건에 참여하지 않은 DEPTNO와 LOC가 2개의 칼럼으로 표시

 

(11) 이번에는 세 개의 칼럼명이 모두 같은 DEPT와 DEPT_TEMP 테이블을 LOC와 DEPTNO 2개 칼럼을 이용한 [INNER] JOIN의 USING 조건절로 수행한다. 

SELECT *
FROM DEPT JOIN DEPT_TEMP
USING (LOC, DEPTNO);
LOC, DEPTNO가 첫 번째, 두 번째 칼럼으로 출력되고,
JOIN 조건에 참여하지 않은 DNAME 칼럼은 2개의 칼럼으로 표시

 

(12) 이번에는 DEPTNO, DNAME 2개의 칼럼을 이용한 [INNER] JOIN의 USING 조건 절로 수행한다. 

SELECT *
FROM DEPT JOIN DEPT_TEMP
USING (DEPTNO, DNAME);
DNAME의 내용이 바뀐 부서번호 20, 30의 경우는 결과에서 제외된 것을 알 수 있다.
USING에 사용된 DEPTNO, DNAME이 첫 번째, 두 번째 칼럼으로 출력
JOIN 조건에 참여하지 않은 LOC가 2개의 칼럼으로 표시

6. ON 조건절

: JOIN 서술부(ON 조건절)와 비 JOIN 서술부(WHERE 조건절)를 분리하여 이해가 쉬우며, 칼럼명이 다르더라도 JOIN 조건을 사용 가능

 

(13) 사원 테이블과 부서 테이블에서 사원 번호와 사원 이름, 소속부서 코드, 소속부서 이름을 출력

SELECT E.EMPNO, E.ENAME, E.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D
ON (E.DEPTNO = D.DEPTNO);


ON 조건절을 사용할 경우

같은 이름을 가진 모든 칼럼들에 대한 동등 조건이지만,
(1) 임의의 JOIN 조건을 지정하거나,

(2) 이름이 다른 칼럼명을 JOIN 조건으로 사용하거나,
(3) JOIN 칼럼을 명시하기 위해서

 

특징

: ALIAS나 테이블 명과 같은 접두사를 사용하여 SELECT에 사용되는 칼럼을 논리적으로 명확하게 지정해야한다.

-> WHERE 절의 JOIN 조건과 같은 기능을 하면서도, 명시적으로 JOIN의 조건 구분 가능

 

가. WHERE 절과의 혼용

(14) ON 조건절과 WHERE 검색 조건은 충돌 없이 사용할 수 있다. 부서코드 30인 부서 의 소속 사원 이름 및 소속 부서 코드, 부서 코드, 부서 이름을 찾아본다.

SELECT E.ENAME, E.DEPTNO, D.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D
ON (E.DEPTNO = D.DEPTNO) WHERE E.DEPTNO = 30;

 

나. ON 조건절 + 데이터 검증 조건 추가

: 검색 조건 목적인 경우는 WHERE 절을 사용할 것

 

(15) 매니저 사원번호가 7698번인 사원들의 이름 및 소속 부서 코드, 부서 이름을 찾아 본다. 

SELECT E.ENAME, E.MGR, D.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D
ON (E.DEPTNO = D.DEPTNO AND E.MGR = 7698);

위 SQL과 아래 SQL은 같은 결과를 얻을 수 있다.

SELECT E.ENAME, E.MGR, D.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
WHERE E.MGR = 7698;

 

다. ON 조건절 예제

(16) 팀과 스타디움 테이블을 스타디움ID로 JOIN하여 팀이름, 스타디움ID, 스타디움 이름 을 찾아본다. 

SELECT TEAM_NAME, TEAM.STADIUM_ID, STADIUM_NAME
FROM TEAM JOIN STADIUM
ON TEAM.STADIUM_ID = STADIUM.STADIUM_ID ORDER BY STADIUM_ID;

위 SQL은 STADIUM_ID라는 공통된 칼럼이 있기 때문에 아래처럼 USING 조건절로 구현 할 수도 있다.

SELECT TEAM_NAME, STADIUM_ID, STADIUM_NAME
FROM TEAM JOIN STADIUM USING (STADIUM_ID)
ORDER BY STADIUM_ID;

위 SQL은 고전적인 방식인 WHERE 절의 INNER JOIN으로 구현할 수도 있다.

SELECT TEAM_NAME, TEAM.STADIUM_ID, STADIUM_NAME
FROM TEAM, STADIUM
WHERE TEAM.STADIUM_ID = STADIUM.STADIUM_ID
ORDER BY STADIUM_ID

 

(17) 팀과 스타디움 테이블을 팀ID로 JOIN하여 팀이름, 팀ID, 스타디움 이름을 찾아본다.

STADIUM에는 팀ID가 HOMETEAM_ID라는 칼럼으로 표시되어 있다

SELECT TEAM_NAME, TEAM_ID, STADIUM_NAME
FROM TEAM JOIN STADIUM
ON TEAM.TEAM_ID = STADIUM.HOMETEAM_ID
ORDER BY TEAM_ID;

위 SQL은 고전적인 방식인 WHERE 절의 INNER JOIN으로 구현할 수도 있다.


SELECT TEAM_NAME, TEAM_ID, STADIUM_NAME
FROM TEAM, STADIUM
WHERE TEAM.TEAM_ID = STADIUM.HOMETEAM_ID
ORDER BY TEAM_ID;

위 SQL은 TEAM_ID와 HOMETEAM_ID라는 다른 이름의 칼럼을 사용하기 때문에 USING 조건절을 사용할 수는 없다.

라. 다중 테이블 JOIN

(18) 사원과 DEPT 테이블의 소속 부서명, DEPT_TEMP 테이블의 바뀐 부서명 정보를 출력

SELECT E.EMPNO, D.DEPTNO, D.DNAME, T.DNAME New_DNAME
FROM EMP E JOIN DEPT D
ON (E.DEPTNO = D.DEPTNO) JOIN DEPT_TEMP T
ON (E.DEPTNO = T.DEPTNO);

위 SQL은 고전적인 방식인 WHERE 절의 INNER JOIN으로 구현할 수도 있다.

SELECT E.EMPNO, D.DEPTNO, D.DNAME, T.DNAME New_DNAME
FROM EMP E, DEPT D, DEPT_TEMP T
WHERE E.DEPTNO = D.DEPTNO
AND E.DEPTNO = T.DEPTNO;

 

(19) GK 포지션의 선수별 연고지명, 팀명, 구장명을 출력한다.

SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지명, T.TEAM_NAME 팀명, S.STADIUM_NAME 구장명
FROM PLAYER P JOIN TEAM T
ON P.TEAM_ID = T.TEAM_ID JOIN STADIUM S
ON T.STADIUM_ID = S.STADIUM_ID
WHERE P.POSITION = 'GK'
ORDER BY 선수명;

위 SQL은 고전적인 방식인 WHERE 절의 INNER JOIN으로 구현할 수도 있다.

SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지명, T.TEAM_NAME 팀명, S.STADIUM_NAME 구장명
FROM PLAYER P, TEAM T, STADIUM S
WHERE P.TEAM_ID = T.TEAM_ID
AND T.STADIUM_ID = S.STADIUM_ID
AND P.POSITION = 'GK'
ORDER BY 선수명;

 

(20) 홈팀이 3점 이상 차이로 승리한 경기의 경기장 이름, 경기 일정, 홈팀 이름과 원정 팀 이름 정보를 출력한다.

SELECT ST.STADIUM_NAME, SC.STADIUM_ID, SCHE_DATE, HT.TEAM_NAME, AT.TEAM_NAME, HOME_SCORE, AWAY_SCORE
FROM SCHEDULE SC JOIN STADIUM ST
ON SC.STADIUM_ID = ST.STADIUM_ID JOIN TEAM HT
ON SC.HOMETEAM_ID = HT.TEAM_ID JOIN TEAM AT
ON SC.AWAYTEAM_ID = AT.TEAM_ID
WHERE HOME_SCORE >= AWAY_SCORE +3;

위 SQL은 고전적인 방식인 WHERE 절의 INNER JOIN으로 구현할 수도 있다.

SELECT ST.STADIUM_NAME, SC.STADIUM_ID, SCHE_DATE, HT.TEAM_NAME, AT.TEAM_NAME, HOME_SCORE, AWAY_SCORE
FROM SCHEDULE SC, STADIUM ST, TEAM HT, TEAM AT
WHERE HOME_SCORE> = AWAY_SCORE +3
AND SC.STADIUM_ID = ST.STADIUM_ID
AND SC.HOMETEAM_ID = HT.TEAM_ID
AND SC.AWAYTEAM_ID = AT.TEAM_ID;

7. CROSS JOIN

:일반 집합 연산자의 PRODUCT의 개념으로 테이블 간 JOIN 조건이 없는 경우 생길 수 있는 모든 데이터의 조합

두 개의 테이블에 대한 CARTESIAN PRODUCT 또는 CROSS PRODUCT와 같은 표현으로,

 

-> 결과는 양쪽 집합의 M*N 건의 데이터 조합이 발생

 

(21) 사원 번호와 사원 이름, 소속부서 코드와 소속부서 이름을 찾아본다.

SELECT ENAME, DNAME
FROM EMP CROSS JOIN DEPT
ORDER BY ENAME;

 

(22) NATURAL JOIN의 경우 WHERE 절에서 JOIN 조건을 추가할 수 없지만, CROSS JOIN의 경우 WHERE 절에 JOIN 조건을 추가할 수 있다. 그러나, 이 경우는 CROSS JOIN 이 아니라 INNER JOIN과 같은 결과를 얻기 때문에 CROSS JOIN을 사용하는 의미가 없어지므로 권고하지 않는다. 

SELECT ENAME, DNAME
FROM EMP CROSS JOIN DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;

위 SQL과 아래 SQL은 같은 결과를 얻을 수 있다.

SELECT ENAME, DNAME
FROM EMP INNER JOIN DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;
데이터 웨어하우스의 개별DIMENSION(차원)을 FACT(사실) 칼럼과 JOIN하기 전에
모든 DIMENSION의 CROSS PRODUCT를 먼저 구할 때 유용하게 사용가능

 


8. OUTER JOIN

: JOIN 조건에서 동일한 값이 없는 행도 반환할 때 사용

 

즉, TAB1 테이블이 TAB2 테이블을 JOIN 하되,
1) TAB2의 JOIN 데이터가 있는 경우TAB2의 데이터를 함께 출력하고,
2) TAB2의 JOIN 데이터가 없는 경우에도 TAB1의 모든 데이터를 표시

JOIN 조건을 FROM 절에서 정의하겠다는 표시이므로 USING 조건절이나 ON 조건절을 필수적으로 사용해야 한다. LEFT/RIGHT OUTER JOIN 의 경우에는 기준이 되는 테이블이 조인 수행시 무조건 드라이빙 테이블이 된다.

 

가. LEFT OUTER JOIN

:먼저 표기된 좌측 테이블에 해당하는 데이터를 먼저 읽은 후, 나중 표기된 우측 테이블에서 JOIN 대상 데이터를 읽어온다.

 

1) B의 JOIN 칼럼에서 같은 값이 있을 때 그 해당 데이터를 가져오고,

2) B의 JOIN 칼럼에서 같은 값이 없는 경우에는 B 테이블에서 가져오는 칼럼들은 NULL 값으로 채운다.

 

(23) STADIUM에 등록된 운동장 중에는 홈팀이 없는 경기장도 있다. STADIUM과 TEAM을 JOIN 하되 홈팀이 없는 경기장의 정보도 같이 출력

SELECT STADIUM_NAME, STADIUM.STADIUM_ID, SEAT_COUNT, HOMETEAM_ID, TEAM_NAME
FROM STADIUM LEFT OUTER JOIN TEAM
ON STADIUM.HOMETEAM_ID = TEAM.TEAM_ID
ORDER BY HOMETEAM_ID;

OUTER는 생략 가능한 키워드이므로 아래 SQL은 같은 결과를 얻을 수 있다.

SELECT STADIUM_NAME, STADIUM.STADIUM_ID, SEAT_COUNT, HOMETEAM_ID, TEAM_NAME
FROM STADIUM LEFT JOIN TEAM
ON STADIUM.HOMETEAM_ID = TEAM.TEAM_ID
ORDER BY HOMETEAM_ID;
LEFT OUTER JOIN을 사용하였기 때문에
홈팀이 없는 경기장의 정보까지 추가로 출력

 

나. RIGHT OUTER JOIN

: 반대로 우측 테이블이 기준이 되어 결과를 생성한다.

 

즉, A의 JOIN 칼럼에서 같은 값이 있을 때 그 해당 데이터를 가져오고, A의 JOIN 칼럼에서 같은 값이 없는 경우에는 A 테이블에서 가져오는 칼럼들은 NULL 값으로 채운다.

 

(24) DEPT에 등록된 부서 중에는 사원이 없는 부서도 있다. DEPT와 EMP를 조인하되 사원이 없는 부서 정보도 같이 출력

 

SELECT E.ENAME, D.DEPTNO, D.DNAME
FROM EMP E RIGHT OUTER JOIN DEPT D
ON E.DEPTNO = D.DEPTNO;

OUTER는 생략 가능한 키워드이므로 아래 SQL은 같은 결과를 얻을 수 있다.

SELECT E.ENAME, D.DEPTNO, D.DNAME, D.LOC
FROM EMP E RIGHT JOIN DEPT D
ON E.DEPTNO = D.DEPTNO;

 

RIGHT OUTER JOIN을 사용하였기 때문에,
사원이 배정되지 않은 부서번호 40의 OPERATIONS 부서의 LOC 정보까지 출력

 

다. FULL OUTER JOIN

: 모든 데이터를 읽어 JOIN하여 결과를 생성

 

즉, RIGHT OUTER JOIN과 LEFT OUTER JOIN의 결과를 합집합으로 처리한 결과와 동일하다.

단, UNION ALL이 아닌 UNION 기능과 같으므로 중복되는 데이터는 삭제

 

(25) DEPT 테이블과 DEPT_TEMP 테이블의 FULL OUTER JOIN 사례를 만들기 위해 DEPT_TEMP의 DEPTNO를 수정한다. 결과적으로 DEPT_TEMP 테이블의 새로운 DEPTNO 데이터는 DEPT 테이블의 DEPTNO와 2건은 동일하고 2건은 새로운 DEPTNO가 생성된다. 

UPDATE DEPT_TEMP
SET DEPTNO = DEPTNO + 20;

SELECT * FROM DEPT_TEMP;

 

(26) DEPTNO 기준으로 DEPT와 DEPT_TEMP 데이터를 FULL OUTER JOIN으로 출력

SELECT *
FROM DEPT FULL OUTER JOIN DEPT_TEMP
ON DEPT.DEPTNO = DEPT_TEMP.DEPTNO;

OUTER는 생략 가능한 키워드이므로 아래 SQL은 같은 결과를 얻을 수 있다.

SELECT *
FROM DEPT FULL JOIN DEPT_TEMP
ON DEPT.DEPTNO = DEPT_TEMP.DEPTNO;


위 SQL과 아래 SQL은 같은 결과를 얻을 수 있다.

SELECT L.DEPTNO, L.DNAME, L.LOC, R.DEPTNO, R.DNAME, R.LOC
FROM DEPT L LEFT OUTER JOIN DEPT_TEMP R
ON L.DEPTNO = R.DEPTNO
UNION
SELECT L.DEPTNO, L.DNAME, L.LOC, R.DEPTNO, R.DNAME, R.LOC
FROM DEPT L RIGHT OUTER JOIN DEPT_TEMP R
ON L.DEPTNO = R.DEPTNO;
FULL OUTER JOIN을 사용하였기 때문에,
DEPT 테이블에만 있는 부서번호 10, 20의 부서와
DEPT_TEMP 테이블에만 있는 부서번호 50, 60의 부서 정보까지 같이 출력

 

9. INNER vs OUTER vs CROSS JOIN 비교

1)INNER JOIN

:양쪽 테이블에 모두 존재하는

키 값이 B-B, C-C 인 2건이 출력된다.

 

2) LEFT OUTER JOIN.

: TAB1을 기준으로

키 값 조합이 B-B, C-C, D-NULL, E-NULL 인 4건이 출력된다.

 

3)RIGHT OUTER JOIN

: TAB2를 기준으로

키 값 조합이 NULL-A, B-B, C-C 인 3건이 출력된다.

 

4) FULL OUTER JOIN

: 40 R&D DALLAS 50 MARKETING CHICAGO 60 OPERATIONS BOSTON 6개의 행이 선택되었다.

양쪽 테이블을 기준으로

키 값 조합이 NULL-A, B-B, C-C, D-NULL, E-NULL 인 5건이 출력된다.

 

 

5)CROSS JOIN

: JOIN 가능한 모든 경우의 수를 표시하지만 단, OUTER JOIN은 제외한다.

양쪽 테이블 TAB1과 TAB2의 데이터를 곱한 개수 4 * 3 = 12건이 추출된다.

키 값 조합이 B-A, B-B, B-C, C-A, C-B, C-C, D-A, D-B, D-C, E-A, E-B, E-C 인 12건이 출력된다.

 

 

 

 

반응형