Join
JOIN
두 개 이상의 테이블이 서로 관계되어있는 상태일 때의 경우. JOIN이란 두 개 이상의 테이블을 서로 묶어서 하나의 결과 집합으로 만들어내는 것이다.
두 테이블의 colum을 합친다는 개념. (테이블 1행 + 2행 > 열을 결합, 하나의 행)
예를 들어, 사번, 사원명, 부서명을 조회할 때, SELECT department_id FROM employees WHERE IN (SELECT department_id FROM departmets); 하나의 테이블을 다룬다면, 부서명은 조회가 불가능하다. 그러나 JOIN의 경우 두 테이블을 연관지으면서, 데이터를 가져올 수 있다.
INNER JOIN
: JOIN을 어떤 조건(WHERE) 없이 사용할 경우, 조인된 중복된 모든 코드들이 함께 출력된다. 필요한 행을 원할때 WHERE절에 필요한 조건문을 넣어준다.
SELECT employee_id, first_name, employees.department_id, department_name FROM employees, departments WHERE employees.department_id = departments.department_id;
- 중복된 것은 어떤 것을 가져올지 명시해야 한다. department_id가 employees와 department의 테이블에 중복되기 때문에, 결과적으로 값은 같지만 SELECT에서는 하나의 테이블을 명시해야 한다.
-
FROM 조회 테이블이 3개라면, JOIN 조건은 최소 2개가 된다. 조회 테이블 - 1이 조건의 최소 개수이다.
-
TABLE의 별칭 주기
해당 테이블을 명시할 때, 그 테이블명 때문에 코드가 복잡해질 수 있기 때문에 별칭을 활용하도록 한다.
SELECT employee_id, first_name, e.department_id, department_name FROM employees e, departments d WHERE e.department_id = d.department_id;
OUTER JOIN
INNER JOIN을 사용하면 조인의 조건에 만족된 행만 조회된다. OUTER JOIN은 조건에 만족되지 않는 행까지도 포함시킨다.
INNER JOIN시 만족되지 않는 행을 조회할 때, 해당하는 WHERE절 안 해당 테이블 뒤에(+)를 붙인다.
예를 들어 null 존재하지 않더라도 null의 존재를 조회해야 할 때 (+) (+)는 값이 없는 쪽에 붙이면 된다.
주의: 양쪽 다에는 붙일 수 없다. 조인 시 없는 쪽의 데이터를 조회하고 싶은 쪽에 (+) 한다.
각 사번 이름 부서명을 조회하되 부서 없는 사원도 포함하여 조회:
SELECT employee_id, first_name, e.department_id, department_name FROM employees e, departments d WHERE e.department_id = d.department_id(+);
department에 해당하는 데이터가 있는데 employees쪽의 데이터가 부족, 추가해서 보여달라. 즉 각 부서에 들어가있는 부서명, 부서사원명, 사번을 조회하되 부서원이 하나도 없는 부서명도 포함해서 조회:
SELECT employee_id, first_name, e.department_id, department_name FROM employees e, departments d WHERE e.department_id(+) = d.department_id;
조건을 만족하는 것만 보여달라는 INNER JOIN, 반면 JOIN할 것이 없더라도 같이 출력해달라는 것이 OUTER JOIN
예제 ) LONDON 도시에 근무하는 사원명, 부서명, 도시명을 조회
SELECT first_name, department_name, city FROM employees e, departments d, locations l WHERE e.department_id = d.department_id and d.location_id = l.location_id and UPPER(city) = 'LONDON'
예제) IT 관련 부서(부서명에 IT 포함)의 사원명, 부서명, 도시명 조회
SELECT first_name, department_name, city FROM employees e, departments d, locations l WHERE e.department_id = d.department_id and d.location_id = l.location_id and department_name LIKE '%IT%';
SELF JOIN
자기 자신(테이블)과 자기 자신(테이블)이 JOIN 하는 경우를 SELF JOIN이라고 한다.
- 복사본을 하나 더 갖고있다는 개념으로 이해하면 된다.
- SELF JOIN은 ALIAS가 필수이다.
예제) employees 테이블 내 사번, 내 이름, 상사 사번, 상사 이름 조회
SELECT me.employee_id, me.first_name, me.manager_id, man.employee_id, man.first_name FROM employees me, employees man WHERE me.manager_id = man.employee_id(+);
예제)내가 내 상사보다 급여 많이 받는 사원이 있다면, 사원의 이름 급여를 출력한다.
SELECT me.first_name, me.salary FROM employees me, employees man WHERE me.manager_id = man.employee_id and me.salary > man.salary;
CROSS JOIN
: WHERE(조건)절 필요, 무의미한 조인을 의미한다.
표준 JOIN과 오라클 JOIN
조인 방법은 표준(ANSI)와 오라클 문법이 있다. 다음의 표를 참조하도록 한다.
표준 JOIN -ansi | 오라클 JOIN |
---|---|
-innerjoin SELECT a1.name, b1.dept_name FROM A a1 INNER JOIN B b1 on a1.id = b1.id; |
-innerjoin SELECT FROM A a1, B b1, WHERE a1.id = b1.id and .. ; |
-outerjoin SELECT a1.name, b1.dept_name FROM A a1 RIGHT OUTER JOIN B b1 on a1.id = b1.id; |
-outerjoin SELECT FROM A a1, B b1, WHERE a1.id = b1.id(+) and .. ; |
집합연산자
UNION(합집합) | 두 조건을 만족하거나 한 조건만 만족하는 사원들을 모두 조회(1회) |
---|---|
UNION ALL(합집합) | 두 조건 만족하거나 한 조건만 만족하는 사원들 모두 조회 (2회) |
MINUS(차집합) | 조건 하나만 만족하지만 조건 2를 만족하지 못하는 사원들 조회 |
INTERSECT(교집합) | 두 조건 모두 만족하는 사원만 조회 |
UNION
: 독립적인 두 쿼리의 결과를 행으로 합치는 것
예를 들어 사원 테이블에서 사번과 이름을 조회하라고 한다. 그리고 회원 테이블에서 아이디와 이름을 조회하라고 한다. 이것을 따로 따로 조회하는 것이 아닌 하나의 쿼리로 조회하는 것
SELECT 사번, 이름 FROM 사원
UNION
SELECT 아이디, 이름 FROM 회원;
SELECT first_name, department_id, salary FROM employees1 WHERE department_id = 50 UNION SELECT first_name, department_id, salary FROM employees2 WHERE salary <= 5000;
-
UNION만 사용하면 중복된 열은 제거, 데이터가 정렬
-
- UNION ALL
-
중복된 열까지 모두 출력
- MINUS
-
첫번째 조건에 만족하는 사람들에서, 두번째 조건을 만족하는 조회 결과를 제외하라.
SELECT first_name, department_id, salary FROM employees WHERE department_id = 50 MINUS SELECT first_name, department_id, salary FROM employees WHERE salary <= 5000;
INTERSECT
: 첫번째 조건, 두번째 조건 모두를 만족하는 조회 결과를 조회하라
SELECT first_name, department_id, salary FROM employees WHERE department_id = 50 INTERSECT SELECT first_name, department_id, salary FROM employees WHERE salary <= 5000;