개념
수학의 집합에서 합집합과 비슷한 개념입니다. 두개이상의 쿼리 결과값을 합하여 보여줍니다.
UNION : 중복값이 있다면 한번만 보여주고, 정렬해서 보여줍니다.
UNION ALL : 중복값이 있어도 그대로 보여주고, 정렬없이 그대로 보여줍니다.
이 외에도 교집합의 INTERSECT , 차집합의 MINUS가 있습니다.
실제로 UNION 이 정렬까지 포함인지, ORDER BY 를 사용하여도 동일한지 확인해보겠습니다.
테스트
테스트 테이블(EMP)
SQL> select * from EMP;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ------ -------------------------- --------- --------- ------------
7839 KING PRESIDENT 5000 10
7698 BLAKE MANAGER 7839 2850 30
7782 CLARK MANAGER 7839 2450 10
7566 JONES MANAGER 7839 2975 20
7654 MARTIN SALESMAN 7698 1250 1400 30
7499 ALLEN SALESMAN 7698 1600 300 30
7844 TURNER SALESMAN 7698 1500 0 30
7900 JAMES CLERK 7698 950 30
7521 WARD SALESMAN 7698 1250 500 30
7902 FORD ANALYST 7566 3000 20
7369 SMITH CLERK 7902 800 20
7788 SCOTT ANALYST 7566 3000 20
7876 ADAMS CLERK 7788 1100 20
7934 MILLER CLERK 7782 1300 10
14 rows selected.
두개의 쿼리를 동일하게 계속 사용할 것입니다.
A 쿼리
SQL> select empno,ename from emp
where deptno = 10;
EMPNO ENAME
---------- ----------
7839 KING
7782 CLARK
7934 MILLER
B쿼리
SQL> select empno,ename from emp
where job='MANAGER';
EMPNO ENAME
---------- ----------
7698 BLAKE
7782 CLARK
7566 JONES
3 rows selected.
간단히 INTERSECT와 MINUS의 값을 보도록 하겠습니다.
MINUS
SQL> select empno,ename from emp
where deptno = 10
INTERSECT
select empno,ename from emp
where job='MANAGER';
EMPNO ENAME
---------- ----------
7782 CLARK
1 rows selected.
------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | |
| 1 | MINUS | | | | | |
| 2 | SORT UNIQUE | | 3 | 2048 | 2048 | 2048 (0)|
|* 3 | TABLE ACCESS FULL| EMP | 3 | | | |
| 4 | SORT UNIQUE | | 3 | 2048 | 2048 | 2048 (0)|
|* 5 | TABLE ACCESS FULL| EMP | 3 | | | |
------------------------------------------------------------------------
INTERSECT
INTERSECT는 위의 쿼리를 기준으로 아래쿼리와의 교집합인 부분을 빼고 결과를 보여줍니다.
SQL> select empno,ename from emp
where deptno = 10
MINUS
select empno,ename from emp
where job='MANAGER';
EMPNO ENAME
---------- ----------
7839 KING
7934 MILLER
2 rows selected.
------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | |
| 1 | INTERSECTION | | | | | |
| 2 | SORT UNIQUE | | 3 | 2048 | 2048 | 2048 (0)|
|* 3 | TABLE ACCESS FULL| EMP | 3 | | | |
| 4 | SORT UNIQUE | | 3 | 2048 | 2048 | 2048 (0)|
|* 5 | TABLE ACCESS FULL| EMP | 3 | | | |
------------------------------------------------------------------------
MINUS와 INTERSECT 둘다 기본적으로 SORT 연산이 들어가 있어, 테이블의 크기가 크거나 하면 성능상의 이슈가 생길 수도 있겠네요.
그럼 원래 궁금했던 UNION 과 UNION ALL의 결과를 보도록 하겠습니다.
UNION
UNION 결과 CLARK가 한건만 나오고, 정렬까지 되었습니다. SORT 연산으로 인해 순서대로 결과가 보입니다,
(7566 -> 7698 -> 7782 -> 7839 -> 7934)
SQL> select empno,ename from emp
where deptno = 10
union
select empno,ename from emp
where job='MANAGER';
EMPNO ENAME
---------- ----------
7566 JONES
7698 BLAKE
7782 CLARK
7839 KING
7934 MILLER
5 rows selected.
------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | |
| 1 | SORT UNIQUE | | 6 | 2048 | 2048 | 2048 (0)|
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS FULL| EMP | 3 | | | |
|* 4 | TABLE ACCESS FULL| EMP | 3 | | | |
------------------------------------------------------------------------
UNION ALL
CLARK가 두번 출력되고 순서 보장 안됨.
그냥 위의 쿼리와 아래 쿼리 결과값이 순서대로 합쳐져서 보여집니다. SORT연산은 실행계획상에서 보이지 않습니다.
SQL> select empno,ename from emp
where deptno = 10
union all
select empno,ename from emp
where job='MANAGER';
EMPNO ENAME
---------- ----------
7839 KING
7782 CLARK
7934 MILLER
7698 BLAKE
7782 CLARK
7566 JONES
6 rows selected.
--------------------------------------------
| Id | Operation | Name | E-Rows |
--------------------------------------------
| 0 | SELECT STATEMENT | | |
| 1 | UNION-ALL | | |
|* 2 | TABLE ACCESS FULL| EMP | 3 |
|* 3 | TABLE ACCESS FULL| EMP | 3 |
--------------------------------------------
ORDER BY 사용시.
UNION
UNION 의 경우 ORDER BY 사용시, 기본적으로 ORDER BY EMPNO를 사용한 것과 UNION만을 사용한 것이 동일한 결과를 보여줍니다. ORDER BY ENAME(두번째 컬럼)으로 수행시는 ENAME을 기준으로 정렬된 결과를 볼 수 있습니다.
##ORDER BY EMPNO
SQL> select empno,ename from emp
where deptno = 10
union
select empno,ename from emp
where job='MANAGER'
ORDER BY EMPNO;
EMPNO ENAME
---------- ----------
7566 JONES
7698 BLAKE
7782 CLARK
7839 KING
7934 MILLER
5 rows selected.
UNION의 경우 이미 정렬이 되어 있기 때문에, ORDER BY 를 사용해도 결과값이 동일함.
------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | |
| 1 | SORT UNIQUE | | 6 | 2048 | 2048 | 2048 (0)|
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS FULL| EMP | 3 | | | |
|* 4 | TABLE ACCESS FULL| EMP | 3 | | | |
------------------------------------------------------------------------
##ORDER BY ENAME
SQL> select empno,ename from emp
where deptno = 10
union
select empno,ename from emp
where job='MANAGER'
ORDER BY ENAME;
EMPNO ENAME
---------- ----------
7698 BLAKE
7782 CLARK
7566 JONES
7839 KING
7934 MILLER
5 rows selected.
ORDER BY ENAME으로 설정했을때는 결과값의 순서가 달라짐.
------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | |
| 1 | SORT UNIQUE | | 6 | 2048 | 2048 | 2048 (0)|
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS FULL| EMP | 3 | | | |
|* 4 | TABLE ACCESS FULL| EMP | 3 | | | |
------------------------------------------------------------------------
UNION ALL
UNION ALL의 경우, 기본적으로 정렬이 되어 있지 않기 때문에 ORDER BY EMPNO, ORDER BY ENAME의 사용여부에 따라서 결과값이 다르게 보여집니다.
##ORDER BY EMPNO
SQL> select empno,ename from emp
where deptno = 10
union all
select empno,ename from emp
where job='MANAGER'
order by EMPNO;
EMPNO ENAME
---------- ----------
7566 JONES
7698 BLAKE
7782 CLARK
7782 CLARK
7839 KING
7934 MILLER
6 rows selected.
------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | |
| 1 | SORT ORDER BY | | 6 | 2048 | 2048 | 2048 (0)|
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS FULL| EMP | 3 | | | |
|* 4 | TABLE ACCESS FULL| EMP | 3 | | | |
------------------------------------------------------------------------
##ORDER BY ENAME
SQL> select empno,ename from emp
where deptno = 10
union
select empno,ename from emp
where job='MANAGER'
ORDER BY ENAME;
EMPNO ENAME
---------- ----------
7698 BLAKE
7782 CLARK
7566 JONES
7839 KING
7934 MILLER
5 rows selected.
ORDER BY ENAME으로 설정했을때는 결과값의 순서가 달라짐.
------------------------------------------------------------------------
| Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | |
| 1 | SORT UNIQUE | | 6 | 2048 | 2048 | 2048 (0)|
| 2 | UNION-ALL | | | | | |
|* 3 | TABLE ACCESS FULL| EMP | 3 | | | |
|* 4 | TABLE ACCESS FULL| EMP | 3 | | | |
------------------------------------------------------------------------
제가 궁금했던 UNION 사용 시, 정렬까지 보장되는가에 대한 궁금증은 테스트를 통해서 해결되었습니다. 정렬으로 인해서 순서가 보장됩니다. 하지만 UNION만 사용시 첫번째 컬럼 기준으로 정렬이 일어나고 다른 컬럼의 정렬을 하려면 ORDER BY [다른컬럼]식으로 추가해주어야 합니다.
'Oracle > 운영' 카테고리의 다른 글
[split] maxvalue가 있는 range 파티션에 다음 파티션 추가하기 (0) | 2022.11.11 |
---|---|
[ASM] asmcmd에도 alias가 있다? (0) | 2022.11.05 |
[12c 이상] 재기동 없이 패치정보가 alert log에 뜨는 경우? (0) | 2022.10.24 |
Full Table Scan 시 Direct Path Read ? (0) | 2022.10.17 |
[SQL 성능 체크 tool]SQLHC 와 SQLT (2) | 2022.09.23 |
댓글