JOINJOIN여러 테이블의 데이터를 결합하여 하나의 결과 집합을 생성하는 SQL 절이다. 기본적으로 두 개 이상의 테이블을 연결하며, 테이블 간 관계를 활용하여 데이터를 조회한다.
JOIN의 필요성은 다음과 같다.
JOIN 사용.INNER JOIN두 테이블 간에 일치하는 데이터만 반환한다. 기본적인 JOIN 방식이다.
SELECT E.NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
INNER JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
SELECT E.NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E, DEPARTMENTS D
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID;
LEFT OUTER JOINLEFT 테이블의 모든 행과 일치하는 RIGHT 테이블의 데이터를 반환한다. 일치하지 않을 경우 NULL을 반환한다.
SELECT E.NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
LEFT OUTER JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
RIGHT OUTER JOINRIGHT 테이블의 모든 행과 일치하는 LEFT 테이블의 데이터를 반환한다. 일치하지 않을 경우 NULL을 반환한다.
SELECT E.NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
RIGHT OUTER JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
FULL OUTER JOINLEFT 테이블과 RIGHT 테이블의 모든 행을 반환한다. 일치하지 않는 데이터는 NULL을 반환한다.
SELECT E.NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
FULL OUTER JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
SELF JOIN같은 테이블을 두 번 사용하여 JOIN을 수행한다. 주로 계층 구조를 표현할 때 사용한다.
SELECT E1.NAME AS EMPLOYEE, E2.NAME AS MANAGER
FROM EMPLOYEES E1
JOIN EMPLOYEES E2
ON E1.MANAGER_ID = E2.EMPLOYEE_ID; --E1: 자식 테이블, E2: 부모 테이블
사원코드 EMPLOYEE_ID와 사수코드 MANAGER_ID를 ON으로 연결한다. E1의 사원코드가 E2의 사수코드와 일치하는지 확인하기 때문에 E1은 자식 테이블, E2는 부모 테이블이다. 결과는 다음과 같다.

같은 테이블을 여러 번 조회하는 것보다 계층 쿼리를 활용하는 것이 더 적절하다.
CROSS JOIN두 테이블 간의 모든 행의 조합을 반환(Cartesian Product)하며, JOIN 조건이 없는 경우 발생한다.
SELECT E.NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
CROSS JOIN DEPARTMENTS D;
E 테이블의 크기가 이고 D 테이블의 크기가 일 때, CROSS JOIN한 테이블의 크기는 이다.
NATURAL JOIN동일한 이름의 컬럼을 기준으로 JOIN한다. 조건을 명시하지 않아도 자동으로 연결한다.
SELECT NAME, DEPARTMENT_NAME
FROM EMPLOYEES
NATURAL JOIN DEPARTMENTS;
EMPLOYEES테이블과DEPARTMENTS테이블은DEPARTMENT_ID와MANAGER_ID를 동일한 컬럼으로 갖는다. 이때SELECT하는 컬럼 리스트를EMPLOYEES.DEPARTMENT_ID와 같이 테이블을 명시하지 않는다.```sql SELECT NAME, DEPARTMENT_NAME, DEPARTMENT_ID, MANAGER_ID FROM EMPLOYEES NATURAL JOIN DEPARTMENTS;
현업에서
NATURAL JOIN을 자주 사용하지는 않는다.
JOIN 사용 시 유의사항JOIN 조건 누락JOIN 조건이 없으면 CROSS JOIN과 동일한 결과가 발생.NULL 처리OUTER JOIN 시 NULL 값을 처리하는 로직 필요.JOIN은 성능 저하가 가능하며, 적절한 인덱스 설정 필요.JOIN 예제--고객 이름과 그 고객이 보유한 계좌 유형을 조회
SELECT C.NAME, A.ACCOUNT_TYPE
FROM CUSTOMERS C
INNER JOIN ACCOUNTS A
ON C.CUSTOMER_ID = A.CUSTOMER_ID;
SELECT C.NAME, A.ACCOUNT_TYPE
FROM CUSTOMERS C, ACCOUNTS A
WHERE C.CUSTOMER_ID = A.CUSTOMER_ID;
--고객 이름과 그 고객이 수행한 거래 금액
SELECT C.NAME, T.AMOUNT
FROM CUSTOMERS C
INNER JOIN ACCOUNTS A
ON C.CUSTOMER_ID = A.CUSTOMER_ID
INNER JOIN TRANSACTIONS T
ON A.ACCOUNT_ID = T.ACCOUNT_ID;
--모든 고객의 이름과 각 고객이 보유한 계좌 유형을 조회
SELECT C.NAME, A.ACCOUNT_TYPE
FROM CUSTOMERS C
LEFT OUTER JOIN ACCOUNTS A
ON C.CUSTOMER_ID = A.CUSTOMER_ID;
--모든 고객과 지점을 조합하여 조회
SELECT C.NAME CUSTOMER_NAME, B.NAME BRANCH_NAME
FROM CUSTOMERS C
CROSS JOIN BRANCHES B;
CROSS JOIN과NATURAL JOIN은 테이블 간의 참조 관계가 필수적이지 않기 때문에ON키워드를 사용하지 않는다.
Oracle
JOIN
OUTER JOIN을 다음과 같이 표현할 수도 있다.SELECT E.EMPLOYEE_ID, E.NAME EMPLOYEE_NAME, D.DEPARTMENT_NAME, D.LOCATION FROM EMPLOYEES E LEFT OUTER JOIN DEPARTMENTS D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID; SELECT E.EMPLOYEE_ID, E.NAME EMPLOYEE_NAME, D.DEPARTMENT_NAME, D.LOCATION FROM EMPLOYEES E, DEPARTMENTS D WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID (+);