개요
- 관계형 데이터베이스에서 SQL을 이용해 테이블간 '관계'를 맺는 방법.
- 관계형 데이터베이스는 최소한의 데이터를 테이블에 담고 있어 원하는 정보를 테이블에서 조회하려면 한 개 이상의 테이블에서 데이터를 읽어와야 되는 경우가 많다.
- 이 때, 테이블간 관계를 맺기 위한 연결고리 역할이 필요한데, 두 테이블에서 같은 데이터를 저장하는 컬럼이 연결고리가 된다.
JOIN
하나 이상의 테이블에서 데이터를 조회하기 위해 사용.
수행 결과는 하나의 Result Set으로 나옴
- 기존에 서로 다른 테이블의 데이터를 조회 할 경우 아래와 같이 따로 조회 한다.
-- 직원번호, 직원명, 부서코드, 부서명을 조회 하고자 할 때
SELECT EMP_ID, EMP_NAME, DEPT_CODE
FROM EMPLOYEE;
-- 직원번호, 직원면, 부서코드는 EMPLOYEE테이블에 조회가능
-- 부서명은은 DEPARTMENT테이블에서 조회 가능
SELECT DEPT_ID, DEPT_TITLE
FROM DEPARTMENT;
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);
-- EMPLOYEE 테이블과 DEPARTMENT 테이블을 연결할 때
-- DEPT_CODE라는 컬럽과 DEPT_ID 컬럼이 같은 값ㅇ르 가지고 있으므로
-- 해당 칼럼들을 기준으로 연결
내부조인(INNER JOIN)
== 등가 조인(EQUAL JOIN)
연결되는 컬럼의 값이 일치하는 행들만 조인됨
(일치하는 값이 없는 행은 조인에서 제외됨)
연결에 사용할 두 컬럼명이 다른 경우
-- EMPLOYEE 테이블, DEPARTMENT 테이블을 참조하여
-- 사번, 이름, 부서코드, 부서명 조회
-- EMPLOYEE 테이블에 DEPT_CODE컬럼과 DEPARTMENT 테이블에 DEPT_ID 컬럼은
-- 서로 같은 부서 코드를 나타낸다.
--> 이를 통해 두 테이블이 관계가 있음을 알고 조인을 통해 데이터 추출이 가능.
-- ANSI
-- 연결에 사용할 컬럼명이 다른경우 ON()을 사용
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);
-- 오라클
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT --FROM절에 사용할 테이블을 모두 작성
WHERE DEPT_CODE = DEPT_ID; -- WHERE절에 같은 값을 가지고 있는 컬럼을 작성
연결에 사용할 두 컬럼명이 같은 경우
-- EMPLOYEE 테이블, JOB테이블을 참조하여
-- 사번, 이름, 직급코드, 직급명 조회
-- ANSI
-- 연결에 사용할 컬럼명이 같은 경우 USING(컬럼명)을 사용함
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
JOIN JOB USING(JOB_CODE);
-- 오라클 -> 별칭 사용
-- 테이블 별로 별칭을 등록할 수 있음.
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, JOB_NAME
FROM EMPLOYEE E, JOB J
WHERE E.JOB_CODE = J.JOB_CODE;
- ☆ 내부 조인의 문제점 ☆
- 연결에 사용되는 컬럼의 값이 NULL이면 조회 결과에 포함되지 않는다.
외부 조인(OUTER JOIN)
두 테이블의 지정하는 컬럼값이 일치하지 않는 행도 조인에 포함을 시킴
☆ 반드시 OUTER JOIN임을 명시해야 한다.
-- OUTER JOIN과 비교할 INNER JOIN 쿼리문
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
/*INNER*/ JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
-- 그냥 JOIN은 INNER JOIN을 뜻한다
LEFT [OUTER] JOIN
합치기에 사용한 두 테이블 중 왼편에 기술된 테이블의 컬럼 수를 기준으로 JOIN
-- ANSI 표준
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);
-- JOIN을 기준으로 왼쪽이 EMPLOYEE 오른쪽이 DEPARTMENT
--> JOIN을 기준으로 왼쪽에 작성된 테이블의 모든 행이 결과(RESULT SET)에 포함된다.
--(현재 EMPLOYEE에는 NULL 값이 포함되어 있다.)
-- 오라클 구문
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID(+);
-- 왼쪽 테이블 컬럼과 오른쪽 테이블 컬럼과 같은 값이 없으면 억지로 추가
RIGHT [OUTER] JOIN
합치기에 사용한 두 테이블 중 오른편에 기술된 테이블의 컬럼 수를 기준으로 JOIN
-- ANSI 표준
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE RIGHT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID);
-- 오라클 구문
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE(+) = DEPT_ID;
FULL [OUTER] JOIN
합치기에 사용한 두 테이블이 가진 모든 행을 결과에 포함
- 오라클 구문은 FULL OUTER JOIN을 사용 못함
-- ANSI 표준
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE FULL OUTER JOIN DEPARTMENT ON(DEPT_TITLE = DEPT_CODE);
교차조인 (CROSS JOIN)
== CARTESIAN PRODUCT)
조인되는 테이블의 각 행들이 모두 매핑된 데이터가 검색되는 방법(곱집합)
JOIN 구문을 잘못 작성하면 결과로 나타난다.
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
CROSS JOIN DEPARTMENT;
비등가 조인(NON EQUAL JOIN)
'='(등호)를 사용하지 않는 조인문
지정한 컬럼 값이 일치하는 경우가 아닌, 값의 범위에 포함되는 행들을 연결하는 방식
SELECT EMP_NAME, SALARY, E.SAL_LEVEL, S.SAL_LEVEL
FROM EMPLOYEE E
JOIN SAL_GRADE S ON (SALARY BETWEEN MIN_SAL AND MAX_SAL);
자체 조인(SELF JOIN)
같은 테이블을 조인.
자기 자신과 조인을 맺음 (똑같은 테이블 두개가 조인)
사번, 이름, 사수 번호, 사수 이름 조회
-- ANSI 표준
SELECT E.EMP_ID, E.EMP_NAME, NVL( E.MANAGER_ID, '없음') , NVL( M.EMP_NAME , '없음')
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE M ON(E.MANAGER_ID = M.EMP_ID);
-- 오라클 구문
SELECT E.EMP_ID, E.EMP_NAME, NVL( E.MANAGER_ID, '없음') , NVL( M.EMP_NAME , '없음')
FROM EMPLOYEE E, EMPLOYEE M
WHERE E.MANAGER_ID = M.EMP_ID;
자연 조인(NATURAL JOIN)
동일한 타입과 이름을 가진 컬럼이 있는 테이블 간의 조인을 간단히 표현하는 방법
반드시 두 테이블 간의 동일한 컬럼명, 타입을 가진 컬럼이 필요
없을 경우 교차조인이 된다.
SELECT EMP_NAME, JOB_NAME
FROM EMPLOYEE
-- JOIN JOB USING(JOB_CODE)
NATURAL JOIN JOB;
다중 조인
N개의 테이블을 조회할 때 사용
- ☆ 순서가 중요하다.
- ☆ JOIN은 순서대로 하나씩 진행된다.
-- EMPLOYEE, DEPARTMENT, LOCATION 조인
-- ANSI 표준
/*3*/SELECT EMP_NAME, DEPT_TITLE, LOCAL_NAME
/*1*/FROM EMPLOYEE
/*2*/JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
JOIN LOCATION ON(LOCATION_ID = LOCAL_CODE);
-- (EMPLOYEE + DEPARTMENT) JOIN LOCATION
-- 오라클 전용
SELECT EMP_NAME, DEPT_TITLE, LOCAL_NAME
FROM EMPLOYEE, DEPARTMENT, LOCATION
WHERE DEPT_CODE = DEPT_ID -- EMPLOYEE, DEPARTMENT 조인
AND LOCATION_ID = LOCAL_CODE; --(EMPLOYEE + DEPARTMENT) JOIN LOCATION
-- 조인 순서를 지키지 않은 경우(에러발생)
--SELECT EMP_NAME, DEPT_TITLE, LOCAL_NAME
--FROM EMPLOYEE
--JOIN LOCATION ON
'Programming language > SQL' 카테고리의 다른 글
SQL - 07 JDBC (0) | 2022.04.09 |
---|---|
SQL - 06 DML (0) | 2022.04.09 |
SQL - 04 GROUP BY & SET OPERATION (0) | 2022.04.09 |
SQL - 03 함수 (0) | 2022.04.09 |
SQL - 02 SELECT(2) (0) | 2022.04.09 |