돌아온 데이터베이스의 시간. 오늘은 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 |