본문 바로가기
데이터베이스

[5일차] JOIN

by Dodledd 2024. 2. 23.

돌아온 데이터베이스의 시간. 오늘은 JOIN에 대해 정리해보도록하자.

 

먼저 JOIN의 정의부터 차근히 읽고가자

<JOIN>
두개 이상의 테이블에서 데이터를 조회하고자 할 때 사용하는 구문
조회 결과는 하나의 결과물(RESULT SET)으로 나옴
관계형 데이터베이스에서는 최소한의 데이터를 각각의 테이블에 담고 있음
(중복 저장을 최소화하기 위해서 최대한 쪼개서 관리함)
=> 관계형 데이터베이스에서 SQL문을 이용한 테이블간 "관계"를맺는 방법
(무작정 다 조회해 오는게 아니라 각 테이블간 연결고리(외래키)를 통해 데이터를 매칭시켜 조회해야한다.)

JOIN은 크게 "오라클 전용 구문"과 "ANSI 구문"(ANSI == 미국국립표준협회)

요약하면 두 테이블을 합치는데 합치는 방법이 두 가지가 있는 것이다.

사실 사용하기로는 ANSI구문이 SQL 전체 공통이라 더욱 많이 사용한다고 한다.

 

 

 

 


용어정리

오라클 전용구문 ANSI구문
등가조인
(EQUAL JOIN)
내부조인
(INNER JOIN) -> JOIN USING / ON
포괄조인
(LEFT OUTER)
(RIGHT OUTER)
왼쪽 외부 조인(LEFT OUTER JOIN)
오른쪽 외부 조인(RIGHT OUTER JOIN)
전체 외부 조인(FULL OUTER JOIN)
자체조인(SELF JOIN)
비등가 조인(NON EAUAL JOIN)
JOIN ON

 

1. 등가조인(EQUAL JOIN) / 내부조인(INNER JOIN)

연결시키는 컬럼의 값이 일치하는 행들만 조회(==일치하는 값이 없는 행은 조회 제외)한다.

 

  • 오라클 전용구문

FROM절에 조회하고자하는 테이블을 나열(,로 구분)
WEHRE절에 매칭시킬 컬럼에 대한 조건을 제시

 

-연결할 두 컬럼명이 다른 경우

SELECT EMP_ID, EMP_NAME,  DEPT_TITLE
 FROM EMPLOYEE,DEPARTMENT
 WHERE DEPT_CODE=DEPT_ID;

 

NULL,D3, D4, D7데이터는 한쪽테이블에서만 존재하기 때문에 제외된 걸 알 수 있다.
일치하는 값이 없는 행은 조회에서 제외된 것을 확인할 수 있다.

 

 

-연결할 두 컬럼명이 같은 경우

 SELECT EMP_ID, EMP_NAME, E.JOB_CODE, j.job_name
 FROM EMPLOYEE E, JOB J
 WHERE E.JOB_CODE = J.JOB_CODE;

컬럼명이 같은데 EMPLOYEE E, JOB J  처럼 별칭을 정해줘서 별칭으로 구분해주지 않는다면 시스템은 어떤 것을 가져올지 몰라 오류가 난다. 때문에 꼭 구분해줘야한다 !

 

  • ANSI 구문

FROM절에 기준이 되는 테이블 하나 기술
OIN절에 같이 조인하고자하는 테이블을 기술 + 매칭시킬 컬럼에 대한 조건도 기술


JOIN USING / JOIN ON

 

-연결할 두 컬럼명이 다른 경우

SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)

ANSI는 두 컬럼명이 다를 경우 무조껀 JOIN ON 으로 사용한다.

 

 

-연결할 두 컬럼명이 같은 경우

1. 별칭 지정해서 구분해주기

SELECT EMP_ID, EMP_NAME, E.JOB_CODE, JOB_NAME
FROM EMPLOYEE E
JOIN JOB J ON (E.JOB_CODE = J.JOB_CODE);

 

2. USING 사용하기

SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
JOIN JOB USING (JOB_CODE);

 

이렇게 ANSI는 두 가지 구문을 사용할 수 있는데 보통 컬럼명이 같으면 조금 더 편한 USING을 사용하고

컬럼명이 다를 시에는 JOIN ON 을 자주 사용한다.

 

2. 포괄조인 / 외부조인(OUTER JOIN)

두 테이블간의 JOIN시 일치하지 않는 행도 포함시켜 조회 가능
단, 반드시 LEFT/RIGHT를 지정해야된다. (기준테이블을 정해야한다)

 

  • LEFT JOIN

두 테이블 중 왼편에 기술된 테이블을 기준으로 JOIN을 한다.

 

-오라클-

SELECT EMP_NAME, DEPT_TITLE, SALARY, SALARY * 12
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID(+);

 

 

-ANSI-

SELECT EMP_NAME, DEPT_TITLE, SALARY, SALARY * 12
FROM EMPLOYEE
LEFT JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);

 

이렇게 보면 오라클은 붙여주는 테이블 즉 기준이 아닌 테이블에 + 를 넣어주고

ANSI는 그냥 JOIN 앞에 LEFT를 작성해주면 된다.

 

  • RIGHT JOIN

두 테이블 중 오른편에 기술된 테이블을 기준으로 JOIN한다

 

-오라클-

SELECT EMP_NAME, DEPT_TITLE, SALARY, SALARY * 12
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID;

 

 

-ANSI-

SELECT EMP_NAME, DEPT_TITLE, SALARY, SALARY * 12
FROM EMPLOYEE
RIGHT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);

마찬가지로 오른편에 있는 테이블을 기준으로 JOIN하겠다 라는 뜻이다.

오라클은 붙여주는 쪽에 +를 써주고

ANSI는 JOIN앞에 RIGHT를 써주면 된다.

 

  • FULL [OUTER] JOIN

두 테이블이 가진 모든 행을 조회할 수 있다(오라클X)

 

-ANSI-

SELECT EMP_NAME, DEPT_TITLE, SALARY,SALARY*12
FROM EMPLOYEE
FULL JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);

두 테이블이 가진 모든 행을 출력한다. *오라클에선 사용할 수 없다 !

 

3. 비등가 조인(NON EQUAL JOIN)

매칭시킬 컬럼에 대한 조건 작성시 '='을 작성하지 않는 조인문
ANSI구문으로는 JOIN ON

 

-오라클-

SELECT EMP_NAME, SALARY, SAL_LEVEL
FROM EMPLOYEE, SAL_GRADE
WHERE SALARY BETWEEN MIN_SAL AND MAX_SAL;

 

 

-ANSI-

SELECT EMP_NAME, SALARY, SAL_LEVEL
FROM EMPLOYEE
JOIN SAL_GRADE ON (SALARY BETWEEN MIN_SAL AND MAX_SAL);

 

 

 4. 자체조인(SELF JOIN)

같은 테이블을 다시 한 번 조인하는 경우

 

-오라클-

SELECT E.EMP_ID, E.EMP_NAME, E.DEPT_CODE,
        M.EMP_ID, M.EMP_NAME, M.DEPT_CODE
FROM EMPLOYEE E, EMPLOYEE M
WHERE E.MANAGER_ID = M.EMP_ID;

 

 

 

-ANSI-

SELECT E.EMP_ID, E.EMP_NAME, E.DEPT_CODE,
        M.EMP_ID, M.EMP_NAME, M.DEPT_CODE
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE M ON(E.MANAGER_ID = M.EMP_ID);

 

 

이번엔 공통점이 있다. 둘 다 자기자신과 JOIN을 하기 때문에 별칭을 적어주는게 필수적인 요소이다.

 

 

5. 다중조인

2개 이상의 테이블을 가지고 JOIN할 때

 

-오라클-

SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE E, DEPARTMENT D, JOB J
WHERE E.DEPT_CODE = D.DEPT_ID
AND E.JOB_CODE = J.JOB_CODE;

별칭을 지정해주고 AND로 이어서 붙여 JOIN해주면 된다.

 

 

-ANSI-

SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE);

ANSI는 JOIN을 이어서 사용해주면 된다.

 

 

 

 

좀 더 복잡하게 봐보면

 

-오라클-

SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME, LOCAL_NAME, NATIONAL_NAME, SAL_LEVEL
FROM EMPLOYEE E, DEPARTMENT D, JOB J, LOCATION L, NATIONAL N, SAL_GRADE S
WHERE E.DEPT_CODE = D.DEPT_ID
  AND E.JOB_CODE = J.JOB_CODE
  AND D.LOCATION_ID = L.LOCAL_CODE
  AND L.NATIONAL_CODE = N.NATIONAL_CODE
  AND E.SALARY BETWEEN S.MIN_SAL AND S.MAX_SAL;

 

 

-ANSI-

SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME, LOCAL_NAME, NATIONAL_NAME, SAL_LEVEL
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN JOB USING (JOB_CODE)
JOIN LOCATION ON (LOCATION_ID = LOCAL_CODE)
JOIN NATIONAL USING (NATIONAL_CODE)
JOIN SAL_GRADE ON (SALARY BETWEEN MIN_SAL AND MAX_SAL);

 

값을 볼 필요는 없다. 문법으로 어떻게 사용하는지 익숙해지고 숙달되어야 한다.!!

 

 

JOIN을 마치며 ...

개인적으로는 ANSI 구문의 JOIN사용하는게 훨씬 명시적이고  사용하기 편한 느낌이든다. 또 ANSI이 많이 사용된다고 하니 뭔가 정감이 가기도 한다... 하지만 오라클도 사용할 때가 있을 터이니 잊지않도록 복습해야겠다.

'데이터베이스' 카테고리의 다른 글

[7일차] DDL(CREATE)  (2) 2024.02.25
[6일차] SUBQUERY  (0) 2024.02.24
[4일차] GROUP함수  (0) 2024.02.22
[3일차] 함수의 마무리  (0) 2024.02.19
[2일차] SELECT 마무리와 FUNTION 기능들  (2) 2024.02.16