UNION
UNION
하든, 중복된 데이터도 모두 쌓는다./* col_a와 col_b와 col_c의 자료형은 반드시 동일해야 한다 */
select col_a from tbl_a
union all
select col_b from tbl_b
union all
select col_c from tbl_c
...
UNION
을 사용한다UNION ALL
과 DISTINCT
를 함꼐 사용하면, UNION
과 같이 작동한다DISTINCT
는 중복된 내용을 날리고 하나만 반환한다JOIN
INNER JOIN
INNER
키워드는 선택사항이다select e.ename, d.loc
from emp e inner join dept d
on e.deptno = d.deptno
'DEPTNO'의 값이 같은 행들이 반환된다.'EMP'테이블과 아래의 테이블이 존재한다고 가정하겠다.
+--------+-------+------+
| ename | job | sal |
+--------+-------+------+
| SMITH | CLERK | 800 |
| ADAMS | CLERK | 1100 |
| JAMES | CLERK | 950 |
| MILLER | CLERK | 1300 |
+--------+-------+------+
'ENAME', 'JOB', 'SAL'은 모두 'EMP' 테이블에 들어있는 값이다.
공통으로 가지고 있는 열이 세 개나 있다.
이럴 때 JOIN
은 어떻게 써야할까?
올바른 결과를 반환하는 데 필요한 모든 열의 테이블을 JOIN한다
select e.empno, e.ename, e.job, e.sal, e.deptno
from emp e join v
on e.ename = v.ename
and e.job = v.job
and e.sal = v.sal;
오라클에서는 다음과 같이 사용한다
select empno, ename, job, sal, deptno
from emp
where (ename, job, sal) in (
select ename, job, sal from emp
intersect
select ename, job, sal from V)
'EMP' 테이블과 'V'테이블에서 'ENAME', 'JOB', 'SAL'칼럼이 공통값을 가지는 부분을 조회한다. 외부쿼리의 SELECT
구문에서 조회해둔 데이터 중 INTERSECT
구문의 결과셋과 'EMP'테이블을 비교하여, 또다시 'ENAME', 'JOB', 'SAL'칼럼이 공통값을 가지는 부분으로 조회 조건을 제한한다.
INTERSECT
는 집합 연산이며, 공통된 행만을 반환하는 것에 주의힌다'EMP' 테이블과 'DEPT' 테이블 모두 'DEPTNO'를 가지고 있다.
그러나 'EMP' 테이블의 'DEPTNO' 칼럼에는 없는 값이 'DEPT' 테이블의 'DEPTNO'에는 있을 수도 있다.
이런 값을 찾을 때 다음과 같은 방법을 사용한다.
MINUS
를 사용한다.
select deptno from dept
minus
select deptno from emp
>>
DEPTNO
40
반대로 하면?
아무 것도 출력되지 않는다.
말 그대로 집합 연산이므로, 집합으로 생각해보면 바로 알 수가 있다.
WHERE
절)select deptno
from dept
where deptno not in (select deptno from emp)
>>
DEPTNO
40
이는 당연하게도 Oracle에서도 동일하게 작동한다.
단, 이 경우에 NULL
값을 신경써야 한다.
만약 위 쿼리에서 'EMP'테이블의 'DEPTNO'칼럼 값에 NULL
이 포함되어 있다면 쿼리는 행을 반환하지 않는다.
FALSE or NULL
은 NULL
이기 때문이다.
이 문제를 방지하기 위해 NOT EXISTS
와 함께 서브쿼리를 사용한다
select d.deptno
from dept d
where not exists(
select 1
from emp e
where d.deptno = e.deptno
)
FROM
절이 실행되면서 alias d 생성WHERE
절이 실행, 외부쿼리의 'WHERE'절에 종속된 내부쿼리가 실행앞과 묘하게 다르다. 없는 '값'을 검색한 앞과 달리 이번엔 '행'을 검색한다.
select d.*
from dept d left join emp e
on d.deptno = e.deptno
where e.deptno is null
>>
+--------+------------+--------+
| deptno | dname | loc |
+--------+------------+--------+
| 40 | OPERATIONS | BOSTON |
+--------+------------+--------+
OUTTER JOIN
을 실행한다NULL
처리NULL
처리 된 값들만 모아주면, 'DEPT' 테이블에는 있지만 'EMP' 테이블에는 없는 행이 반환된다