본문 바로가기
Oracle/운영

UNION 과 UNION ALL

by 취미툰 2022. 10. 26.
반응형

개념

수학의 집합에서 합집합과 비슷한 개념입니다. 두개이상의 쿼리 결과값을 합하여 보여줍니다.

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 [다른컬럼]식으로 추가해주어야 합니다.

반응형

댓글