[데이터베이스개론·SQL] 250116

이슬비·2025년 1월 15일

JOIN

JOIN

여러 테이블의 데이터를 결합하여 하나의 결과 집합을 생성하는 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 JOIN

LEFT 테이블의 모든 행과 일치하는 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 JOIN

RIGHT 테이블의 모든 행과 일치하는 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 JOIN

LEFT 테이블과 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_IDON으로 연결한다. E1의 사원코드가 E2의 사수코드와 일치하는지 확인하기 때문에 E1은 자식 테이블, E2는 부모 테이블이다. 결과는 다음과 같다.

같은 테이블을 여러 번 조회하는 것보다 계층 쿼리를 활용하는 것이 더 적절하다.

CROSS JOIN

두 테이블 간의 모든 행의 조합을 반환(Cartesian Product)하며, JOIN 조건이 없는 경우 발생한다.

SELECT E.NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E
CROSS JOIN DEPARTMENTS D;

E 테이블의 크기가 MM이고 D 테이블의 크기가 NN일 때, CROSS JOIN한 테이블의 크기는 M×NM \times N이다.

NATURAL JOIN

동일한 이름의 컬럼을 기준으로 JOIN한다. 조건을 명시하지 않아도 자동으로 연결한다.

SELECT NAME, DEPARTMENT_NAME
FROM EMPLOYEES
NATURAL JOIN DEPARTMENTS;

EMPLOYEES 테이블과 DEPARTMENTS 테이블은 DEPARTMENT_IDMANAGER_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 JOINNULL 값을 처리하는 로직 필요.
  • 성능
    • 큰 테이블 간 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 JOINNATURAL 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 (+);

0개의 댓글