< JOIN >
두 개 이상의 테이블에서 데이터를 조회하고자 할 때 사용되는 구문
조회 결과는 하나의 결과물(RESULT SET)로 나옴
관계형 데이터베이스는 최소한의 데이터로 각각의 테이블에 데이터를 담고 있음 (중복을 최소화하기 위해 최대한 쪼개서 관리함)
-- 위의 두테이블에서 어떤 사원이 어떤 부서에 속해있는지 궁금함! 코드말고.. 이름으로..
=> 관계형 데이터베이스에서 SQL문을 아용한 테이블간에 "관계"를 맺는 방법
(무작정 다 조회를 해오는게 아니라 각 테이블간 연결고리로써의 데이터를 매칭해서 조회 시켜야함!!)
JOIN 크게 "오라클 전용구문" 과 "ANSI 구문" (ANSI == 미국국립표준협회) => 아스키코드표 만드는 단체!
[ JOIN 용어 정리 ]
1. 등가조인 (EQUAL JOIN) / 내부조인(INNER JOIN)
연결시키는 컬럼의 값이 일치하는 행들만 조인돼서 조회 (== 일치하는 값이 없는 행은 조회에서 제외)
-->> 오라클 전용구문
-- FROM절에 조회하고자 하는 테이블들을 나열 (, 구분자로)
-- WHERE절에 매칭시킬 컬럼(연결고리)에 대한 조건을 제시함
-- 1) 연결한 두 컬럼명이 다른 경우 (EMPLOYEE : DEPT_CODE, DEPARTMENT : DEPT_ID)
-- 사번, 사원명, 부서코드, 부서명을 같이 조회
EMPLOYEE TABLE
SELECT EMP_ID, EMP_NAME, DEPT_CODE
FROM EMPLOYEE;
DEPARTMENT TABLE
SELECT DEPT_ID, DEPT_TITLE
FROM DEPARTMENT;
-- 전체 사원들의 사번, 사원명, 부서코드, 부서명 조회하고자 할 때
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID;
-- 일치하는 값이 없는 행은 조회에서 제외된거 확인 가능
-- DEPT_CODE 가 NULL인 사원 조회 X, DEPT_ID가 D3, D4, D7 조회 X
-- 2) 연결한 두 컬럼명이 같은 경우 (EMPLOYEE : JOB_CODE, JOB : JOB_CODE)
-- 사번, 사원명, 직급코드, 직급명
EMPLOYEE TABLE
SELECT EMP_ID, EMP_NAME, JOB_CODE
FROM EMPLOYEE;
JOB TABLE
SELECT JOB_CODE, JOB_NAME
FROM JOB;
-- 전체 사원들의 사번, 사원명, 직급코드, 직급명 조회 하고자 할 때
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE, JOB
WHERE JOB_CODE = JOB_CODE;
-- ORA-00918: column ambiguously defined 오류
-- ambiguously : 애매하다. 모호하다.
-- 1) 해결방법1. 테이블명을 이용하는 방법
SELECT EMP_ID, EMP_NAME, EMPLOYEE.JOB_CODE, JOB_NAME
FROM EMPLOYEE, JOB
WHERE EMPLOYEE.JOB_CODE = JOB.JOB_CODE;
-- 2) 해결방법2. 테이블에 별칭을 부여해서 이용하는 방법
SELECT EMP_ID, EMP_NAME, E.JOB_CODE, JOB_NAME
FROM EMPLOYEE E, JOB J
WHERE E.JOB_CODE = J.JOB_CODE;
-->> ANSI 구문
-- FROM절에 기준이 되는 테이블을 하나 기술 한 후
-- JOIN절에 같이 조회하고자 하는 테이블 기술 + 매칭시킬 컬럼에 대한 조건도 기술
-- JOIN USING, JOIN ON
-- 1) 연결할 두 컬럼명이 다른 경우 (EMPLOYEE : DEPT_CODE, DEPARTMENT : DEPT_ID)
-- 오로지 JOIN ON 구문으로만 사용 가능!!!
-- 사번, 사원명, 부서코드, 부서명
SELECT EMP_ID, EMP_NAME, DEPT_CODE, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID);
-- 2) 연결할 두 컬럼명이 같은 경우 (E:JOB_CODE, J:JOB_CODE)
-- JOIN ON, JOIN USING 구문 사용 가능!
-- 사번, 사원명, 직급코드, 직급명
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE E
JOIN JOB ON (JOB_CODE = JOB_CODE);
-- ORA-00918: column ambiguously defined
-- 해결방법 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. JOIN USING 구문 사용하는 방법 (두 컬럼명이 일치할때만 사용 가능)
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
JOIN JOB USING(JOB_CODE);
-------------------------------------------------- [ 참고사항 ] --------------------------------------------------
-- 자연조인(NATURAL JOIN) : 각 테이블마다 동일한 컬럼이 한 개만 존재할 경우
SELECT EMP_ID, EMP_NAME, JOB_CODE, JOB_NAME
FROM EMPLOYEE
NATURAL JOIN JOB;
-----------------------------------------------------------------------------------------------------------------------------
-- 추가적인 조건도 당근 제시 가능
-- 직급이 대리인 사원의 이름, 직급명, 급여 조회
-- >> 오라클 전용 구문
SELECT EMP_NAME, JOB_NAME, SALARY
FROM EMPLOYEE E, JOB J
WHERE E.JOB_CODE = J.JOB_CODE
AND J.JOB_NAME = '대리';
-->> ANSI 구문
SELECT EMP_NAME, JOB_NAME, SALARY
FROM EMPLOYEE -- 1
JOIN JOB USING(JOB_CODE) -- 2
WHERE JOB_NAME = '대리'; -- 3
실습문제
-- 1. 부서가 인사관리부인 사원들의 사번, 이름, 보너스 조회
SELECT * FROM EMPLOYEE;
SELECT * FROM DEPARTMENT;
-->> 오라클 전용 구문
SELECT EMP_ID, EMP_NAME, BONUS
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID
AND DEPT_TITLE = '인사관리부';
-->> ANSI 구문
SELECT EMP_ID, EMP_NAME, BONUS
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
WHERE DEPT_TITLE = '인사관리부';
-- 2. DEPARTMENT와 LOCATION을 참고해서 전체 부서의 부서코드, 부서명, 지역코드, 지역명 조회
SELECT * FROM DEPARTMENT; -- LOCATION_ID
SELECT * FROM LOCATION; -- LOCAL_CODE
-->> 오라클 전용 구문
SELECT DEPT_ID, DEPT_TITLE, LOCATION_ID, LOCAL_NAME
FROM DEPARTMENT, LOCATION
WHERE LOCATION_ID = LOCAL_CODE;
-->> ANSI 구문
SELECT DEPT_ID, DEPT_TITLE, LOCATION_ID, LOCAL_NAME
FROM DEPARTMENT
JOIN LOCATION ON (LOCATION_ID = LOCAL_CODE);
-- 3. 보너스를 받는 사원들의 사번, 사원명, 보너스, 부서명 조회
SELECT * FROM EMPLOYEE;
SELECT * FROM DEPARTMENT;
-->> 오라클 전용 구문
SELECT EMP_ID, EMP_NAME, BONUS, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID
AND BONUS IS NOT NULL;
-->> ANSI 구문
SELECT EMP_ID, EMP_NAME, BONUS, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
WHERE BONUS IS NOT NULL;
-- 4. 부서가 총무부가 아닌 사원들의 사원명, 급여, 부서명 조회
SELECT * FROM EMPLOYEE;
SELECT * FROM DEPARTMENT;
-->> 오라클 전용 구문
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE, DEPARTMENT
WHERE DEPT_CODE = DEPT_ID
AND DEPT_TITLE != '총무부';
-->> ANSI 구문
SELECT EMP_NAME, SALARY, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON (DEPT_CODE = DEPT_ID)
WHERE DEPT_TITLE != '총무부';
-- 지금 현재 DEPT_CODE가 NULL 인것은 나오고 있지 않음
--> LEFT JOIN 또는 RIGHT JOIN 으로 해결가능하다. 다음장에서 알아보자~~