2.2.1 표준 조인
STANDARD SQL 개요
일반 집합 연산자

- UNION 연산 - UNION 기능
- INTERSECTION 연산 = INTERSECT 기능
- DIFFERENCE 연산 - EXCEPT 기능 (ORACLE은 MINUS)
- PRODUCT 연산 - CROSS JOIN 기능 (M*N. CARTESIAN PRODUCT)
- UNION ALL 기능 - 특별한 요구 사항이 없다면 공통집합을 중복해서 그대로 보여주기 때문에 정렬 작업이 일어나지 않는 장점
순수 관계 연산자

- SELECT 연산 - WHERE 절
- PROJECT 연산 - SELECT 절
- (NATURAL) JOIN 연산 - 다양한 JOIN 기능들
- DIVIDE 연산 - 사용되지 않음
- 이런 정규화를 거치면 하나의 주제에 관련 있는 엔터티가 여러 개로 나누어지게 되고, 이 엔터티들이 주로 테이블이 되는데, 이렇게 흩어진 엔터티를 연결해서 원하는 데이터를 가져오는 작업이 JOIN
FROM 절 JOIN 형태
- INNER JOIN
- NATURAL JOIN
- USING 조건절
- ON 조건절
- CROSS JOIN
- OUTER JOIN
- 원래 JOIN은 WHERE절에서 사용되는 것으로 알고있음
- INNER JOIN은 WHERE 절에서부터 사용하던 JOIN의 DEFAULT 옵션
- ON 조건절 JOIN
- WHERE 절의 JOIN 조건을 FROM 절의 ON 조건절로 분리하여 표시
- 자연 조인이나 USING 조건절처럼 칼럼명이 똑같아야 된다는 제약없이 칼럼명이 상호 다르더라도 JOIN 조건으로 사용 가능해서 제일 많이 사용됨
INNER JOIN
- 외부 조인과 대비됨
- WHERE 절에서 사용하던 조건을 FROM 절에서 정의하겠다는 표시
- USING 조건절이나 ON 조건절을 필수적으로 사용해야 한다.
SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;
SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP INNER JOIN DEPT
ON EMP.DEPTNO = DEPT.DEPTNO;
- INNER JOIN은 생략하여 JOIN으로 사용하는 것도 가능함.
NATURAL JOIN
- 자연조인이 명시되면, 추가로 USING 조건절, ON 조건절, WHERE 절에서 JOIN 조건을 정의할 수 없다.
SELECT DEPTNO, EMPNO, ENAME, DNAME
FROM EMP NATURAL JOIN DEPT;
- 별명이나 테이블명과 같은 접두사를 붙일 수 없다.
SELECT EMP.DEPTNO, EMPNO, ENAME, DNAME
FROM EMP NATURAL JOIN DEPT;
- 위의 SQL은 불가능
- 와일드카드(*)처럼 칼럼 순서를 지정하지 않으면 자연조인의 기준이 되는 칼럼들이 다른 칼럼보다 먼저 출력
- 반면 INNER JOIN의 경우 테이블의 원래 칼럼 순서대로 데이터가 출력됨
- 이 때 자연조인은 조인에 사용된 같은 이름의 칼럼을 하나로 처리하지만, INNER JOIN은 별개의 칼럼으로 표시한다.
USING 조건절
- 원하는 칼럼에 대해서만 선택적으로 동등조인을 할 수 있다.
SELECT *
FROM DEPT JOIN DEPT_TEMP
USING (DEPTNO);
- USING JOIN은 JOIN에 사용된 같은 이름의 칼럼을 하나로 처리
- USING 조건절을 이용한 동등조인에서도 자연조인과 마찬가지로 별명, 테이블이름 사용 불가
ON 조건절
SELECT E.EMPNO, E.ENAME, E.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D
ON (E.DEPTNO = D.DEPTNO);
- USING 조건절을 이용한 JOIN에서는 JOIN 칼럼에 대해서 별명이나 테이블 명과 같은 접두사를 사용하면 SYNTAX 에러가 발생
- ON 조건절을 사용한 JOIN의 경우에는 별명이나 테이블명과 같은 접두사를 사용하여 SELECT에 사용되는 칼럼을 논리적으로 명확하게 지정해야 한다.
WHERE 절과의 혼용
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 검색 조건은 충돌 없이 사용가능
- 부연설명.. FROM절에 EMP E / DEPT D => 별칭 쓴 거임.
ON 조건절 + 데이터 검증 조건 추가
SELECT E.ENAME, E.MGR, D.DEPTNO, D.DNAME
FROM EMP E JOIN DEPT D
ON (E.DEPTNO = D.DEPTNO
AND E.MGR = 7698);
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 조건절 예제
ON 조건절
SELECT TEAM_NAME, TEAM.STADIUM_ID, STADIUM_NAME
FROM TEAM JOIN STADIUM
ON TEAM.STADIUM_ID = STADIUM.STADIUM_ID
ORDER BY STADIUM_ID;
USING 조건절로도 구현 가능.
SELECT TEAM_NAME, STADIUM_ID, STADIUM_NAME
FROM TEAM JOIN STADIUM
USING (STADIUM_ID)
ORDER BY STADIUM_ID;
- USING (STADIUM_ID)는 양쪽 테이블에 동일하게 있는 칼럼을 의미
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;
- 헷갈려서 하는 부연설명: INNER JOIN은 WHERE, FROM 절에 다 사용가능함.
즉, INNER JOIN이 곧 JOIN임(동일한 기능을 함)
다중 테이블 JOIN
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);
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);
CROSS JOIN
- CARTESIAN PRODUCT 또는 CROSS PRODUCT와 같은 표현
- 집합의 M*N 건의 데이터 조합 발생
SELECT ENAME, DNAME
FROM EMP CROSS JOIN DEPT
WHERE EMP.DEPTNO = DEPTNO;
OUTER JOIN

LEFT OUTER JOIN
- B의 JOIN 칼럼에서 같은 값이 없는 경우에는 NULL 값으로 채운다.
RIGHT OUTER JOIN
- LEFT OUTER JOIN과 반대로 왼쪽 테이블을 NULL 값으로 채움
FULL OUTER JOIN
- UNION ALL이 아닌 UNION 기능과 같으므로 중복되는 데이터는 삭제함
- 양 측에 NULL 값이 만들어질 수 있음
INNER VS OUTER VS CROSS JOIN 비교

- INNER JOIN
- LEFT OUTER JOIN
- RIGHT OUTER JOIN
- FULL OUTER JOIN
- NULL-A, B-B, C-C, D-NULL, E-NULL
- CROSS JOIN
- 4*3 = 12개의 결과
- B-A, B-B, B-C, C-A, C-B ....