티스토리 뷰
집합연산자는 조회(SELECT) 쿼리의 결과를 대상으로 연산을 수행하는 연산자이다. UNION, UNION ALL, INTERSECT, MINUS등이 있다. 조회의 결과를 대상으로 연산을 수행하므로, 여러 개의 SELECT문을 하나의 쿼리로 만드는 연산자라고 할 수 있다.
정리를 하기 전에, 아래와 같은 데이터가 있다고 가정하자
1 2 3 4 5 6 7 8 9 10 11 | 순번 과목명 이름 ---------------------- 1 국어 철수 2 영어 철수 3 수학 철수 1 국어 영희 2 사회 영희 3 과학 영희 4 도덕 영희 5 영어 영희 | cs |
철수는 순서대로 국어, 영어, 수학을 이번학기에 듣고, 영희는 국어, 사회, 과학, 도덕, 영어를 이번학기에 듣는다. 이 데이터를 예로, 집합연산자를 소개하려고 한다.
1. UNION
UNION은 합집합 개념이다. 철수와 영희가 듣는 과목을 각각 조회한 쿼리를 UNION연산으로 처리하면, 철수와 영희가 같이 듣는 국어와 영어는 수행 결과 한번만 나오게 된다. UNION의 사용 예와 결과 예는 아래와 같다.
사용 예
1 2 3 4 5 6 7 | SELECT subject FROM timetable WHERE name='철수' UNION SELECT subject FROM timetable WHERE name='영희'; | cs |
결과 예
1 2 3 4 5 6 7 8 | subject -------- 국어 영어 수학 사회 과학 도덕 | cs |
2. UNION ALL
UNION ALL은 UNION과 매우 유사하다. UNION과의 차이점은, 중복된 항목도 모두 조회한다는 것이다. 사용 예와 결과 예는 아래와 같다.
사용 예
1 2 3 4 5 6 7 | SELECT subject FROM timetable WHERE name='철수' UNION ALL SELECT subject FROM timetable WHERE name='영희'; | cs |
결과 예
1 2 3 4 5 6 7 8 9 10 | subject -------- 국어 영어 수학 국어 사회 과학 도덕 | cs |
3. INTERSECT
INTERSECT는 교집합을 의미한다. 사용 예와 결과 예는 아래와 같다.
사용 예
1 2 3 4 5 6 7 | SELECT subject FROM timetable WHERE name='철수' INTERSECT SELECT subject FROM timetable WHERE name='영희'; | cs |
결과 예
1 2 3 4 | subject -------- 국어 영어 | cs |
4. MINUS
MINUS는 차집합을 의미한다. 먼저 위치한 SELECT문을 기준으로, 다른 SELECT문과 공통된 레코드를 제외한 항목만 추출된다. 사용 예와 결과 예는 아래와 같다.
사용 예
1 2 3 4 5 6 7 | SELECT subject FROM timetable WHERE name='철수' MINUS SELECT subject FROM timetable WHERE name='영희'; | cs |
결과 예
1 2 3 | subject -------- 수학 | cs |
지금까지 집합연산자의 사용에 대해 알아보았다. 집합에 대한 기본적인 연산은 중,고등학교 과정이므로, 어렵지 않게 이해했을 것이다. 다만, 집합연산자를 사용할 때 주의해야할 사항이 몇가지 있는데 이를 짚고 넘어갈 필요가 있다.
▶UNION연산을 보기쉽게 설명한 그림
1. SELECT문들은 같은 개수의 컬럼을 조회해야만 한다.
- 이를 지키지 않을 경우, 에러가 발생한다. 그 이유는 2번에서 설명이 가능하다. 아래와 같은 쿼리는 에러를 발생시킨다.
에러 예
1 2 3 4 5 6 7 | SELECT seq, subject // 순번과 과목명을 조회했다. FROM timetable WHERE name='철수' UNION SELECT subject // 과목명만 조회했다. FROM timetable WHERE name='영희'; | cs |
2. SELECT문들이 여러 개의 컬럼을 조회할 경우, 모든 컬럼에 대해 집합연산을 수행한다.
- 집합연산자로 연결되는 SELECT문들이 여러 개의 컬럼을 조회할 경우, 그 컬럼들을 묶어 하나의 세트로 인식하여 중복여부를 판단한다. 아래와 같은 쿼리를 수행한다고 가정하자.
1 2 3 4 5 6 7 | SELECT seq, subject // 순번, FROM timetable WHERE name='철수' UNION SELECT seq, subject // 순번, 과목명 FROM timetable WHERE name='영희'; | cs |
이 쿼리에 대한 결과는 이전의 UNION연산 예제 쿼리와는 약간 다르다. 아래 결과를 살펴보자
1 2 3 4 5 6 7 8 9 | seq subject --------------- 1 국어 2 영어 2 사회 3 수학 3 과학 4 도덕 5 영어 | cs |
차이를 찾았는가? 과목명으로만 UNION할 때는 영어가 한 번만 도출되었는데, 순번을 같이 묶어 연산하니 철수와 영희의 영어과목은 순번이 달라 둘 다 출력되었다! UNION연산에 여러 컬럼을 적용할 때는 주의해야할 것이다.
3. ORDER BY문은 맨 마지막에만 사용할 수 있다.
- 이는 어찌보면 당연한 것인데, ORDER BY문은 쿼리 수행 결과를 특정 컬럼을 기준으로 정렬하는 것이므로 맨 마지막이 아닌 중간에 수행해버리면 ORDER BY의 수행이 무효화될 것이다.
-끝-
출처 및 참고
홍형경, 『오라클 SQL과 PL/SQL을 다루는 기술』, 길벗(2015)
http://www.softwaretestingclass.com/sql-union/
'IT > DB' 카테고리의 다른 글
[ORACLE] 오라클 SQL 함수 간단 정리 (0) | 2017.02.27 |
---|---|
[ORACLE] SQL의 조건식 정리 (0) | 2017.02.14 |
[ORACLE] SQL의 연산자(Operator) 정리 (0) | 2017.01.16 |
[ORACLE] 오라클의 색인(Index) 사용 (0) | 2016.12.31 |
[ORACLE] ORACLE의 제약조건(Constraints) (0) | 2016.12.20 |