안녕하세요~
오늘은 두 집합을 연결하는 또 다른 연산자 UNION에 대해 알아보겠습니다!
UNION은 위의 사진처럼 TABLES의 행(ROW)을 위 아래로 결합하는 것입니다.
더 자세히 알아볼까요?
집합 연산자란?
두 집합 사이의 합집합 , 교집합, 차집합을 출력하는 연산자 입니다.
그렇다면 JOIN과는 어떠한 차이점이 있을까요?
JOIN VS UNION
JOIN절은 위와같이 옆으로! COLUMN이 추가되며 합쳐지는 형태를 갖습니다.
반면에
UNION절은 위 - 아래로 하나의 COLUMN에 ROW가 추가되는 형태를 갖습니다.
(조인을 더 알고 싶다면 여기로)
먼저, UNION 절의 종류에 대해 알아봅시다!
- UNION ALL: 두 집합의 합집합을 출력하는 연산자
- UNION: 두 집합의 합집합을 출력하는 연산자. (단 중복을 제거하여 반환) - INTEREST: 교집합을 출력하는 연산자 ( 양쪽 쿼리에 공통되는 행을 반환 ) - MINUS: 두 집합 사이의 차집합을 출력하는 연산자로 첫번째 쿼리에 의해 선택되지만 두번째 쿼리 결과 집합에는 없는 모든 행을 반환 |
* 참고: 위에서 의미하는 집합이란 결과 데이터를 의미합니다.
예제를 통해 UNION절의 사용방법에 대해 알아보겠습니다.
[ 고객A 테이블 ]
고객이름 | 나이 | 주소 | 총구매액 | 추천인 |
A | 24 | 서울 | 30000 | null |
B | 29 | 서울 | 10000 | A |
C | 26 | 파주 | 25000 | A |
D | 27 | 제주 | 1000 | B |
예제1. UNION ALL 과 UNION의 차이를 확인해보죠!
SQL1> SELECT 고객이름 FROM 고객 UNION ALL SELECT 고객이름 FROM 고객;
SQL2> SELECT 고객이름 FROM 고객 UNION SELECT 고객이름 FROM 고객; |
고객이름 |
A |
B |
C |
D |
A |
B |
C |
D |
고객이름 |
A |
B |
C |
D |
참고:
INTEREST 와 MINUS 연산자의 경우
위의 UNION ALL/ UNION 자리에 입력하여 결과를 확인하면
쉽게 이해하실 수 있을 것 같아서 PASS!
집합연산자 사용시 주의사항
1. 집합 연산자 위-아래의 쿼리문의 컬럼의 갯수와 데이터 타입이 동일해야한다.
2. ORDER BY절은 맨 아래 쿼리에만 사용할 수 있으며
ORDER BY절을 사용하려면 쿼리문들의 컬럼명과 데이터 타입이 모두 동일해야합니다!
( 특히 SELECT 문에서 NULL값을 두개 이상 사용할 경우!
ALIAS로 COLUMN명을 동일하게 만들어준다!! )
두번째! UNION 절과 함께 알아두면 좋은~
레포팅 함수에 대해 알려드릴께요!
<레포팅함수 종류>
- ROLLUP - CUBE - GROUPING SETS - GROUPING (여기서 다루지 않음) : (리얼) Null ( --> 0)과 grouping되는 결과를 보기위해 어쩔수 없이 null로 출력되는 데이터( --> 1 )를 구분해 주기 위해서 사용하는 함수 |
예제2: 주소, 나이, 주소별 & 나이별 고객의 총 구매액을 구하고
마지막에 전체 고객의 총 구매액을 추가해주세요
-- UNION 절 SQL3> SELECT 주소, 나이, SUM(총구매액) FROM 고객 GROUP BY 주소, 나이 UNION SELECT NULL 주소, NULL 나이, SUM(총구매액) FROM 고객 ORDER BY 주소 ASC; -- ROLLUP절
SQL4> SELECT 주소, 나이, SUM(총구매액) FROM 고객 GROUP BY ROLLUP ( (주소, 나이) ); |
SQL3 & SQL4의 결과
주소 |
나이 |
SUM(총구매액) |
서울 |
24 |
30000 |
서울 |
29 |
10000 |
제주 |
27 |
1000 |
파주 |
26 |
25000 |
null |
null |
30000+10000+1000+25000 |
위와 같이 두개의 SQL문이 실행되야하는 UNION절을
하나의 SQL문이 실행되는 ROLLUP으로 대신 사용하면
속도가 보다 빨라지기 때문에 성능이 더 좋다고 할 수 있겠죠?
위의 SQL2문에서 ROLLUP함수에 ( ( ) ) 두 개의 괄호가 있는 것을 눈치 채셨나요?
만약 괄호를 ( ) 한 개만 사용한다면 어떻게 될까요?
-- ROLLUP절
SQL5> SELECT 주소, 나이, SUM(총구매액) FROM 고객 GROUP BY ROLLUP ( 주소, 나이 ); |
SQL5 결과
주소 |
나이 |
SUM(총구매액) |
서울 |
24 |
30000 |
서울 |
29 |
10000 |
서울 |
null |
30000 + 10000 |
제주 |
27 |
1000 |
제주 |
null |
1000 |
파주 |
26 |
25000 |
파주 |
null |
25000 |
null |
null |
30000+10000+1000+25000 |
위의 색칠되어있는 부분이 추가된 것을 볼 수 있습니다.
이것은 ROLLUP의 특징인데요
'SQL5의 실행 순서'를 보면
1. (주소, 나이)로 그룹핑하여 총합을 구한다
2. (주소)로 그룹핑하여 총합을 구한다
3. (전체) 총합을 구한다
위의 SQL4, SQL5결과를 각각 GROUP SETS로 실행시켜봅시다!
-- SQL4를 GROUP SETS로 SQL6> SELECT 주소, 나이, SUM(총구매액) FROM 고객 GROUP BY GROUP SETS ( (주소, 나이), ( ) );
-- SQL5를 GROUP SETS로
SQL7> SELECT 주소, 나이, SUM(총구매액) FROM 고객 GROUP BY GROUP SETS ( (주소, 나이), (주소), ( ) ); |
따라서
GROUP SETS는 ROLLUP보다 GROUPING된 결과를 더 잘 예상할 수 있어 작성하기도 편하답니다!
참고:
CUBE는 간단히 ROLLUP의 반대라고 생각하면 됩니다!
예제2와 달리 총구매액이 맨 위로 출력됩니다!
오늘은 여기까지!
내일은 서브쿼리로 돌아올겠습니다~
(오늘이 금요일이 아니라니..)
'SQL' 카테고리의 다른 글
ORACLE | 서브쿼리 2탄 - MULTIPLE COLUMN SUBQUERY (0) | 2018.04.06 |
---|---|
ORACLE | 서브쿼리 1탄 - SINGLE / MULTI ROW SUBQUERY & EXISTS (0) | 2018.04.06 |
ORACLE | 3개의 tables를 조인하는 방법! (1) | 2018.04.04 |
ORACLE | JOIN을 사용하는 오라클만의 방법! (0) | 2018.04.03 |
ORACLE | 분석함수 RANK & DENSE_RANK , PIVOT& UNPIVOT (0) | 2018.04.02 |