집합 연산자

연산자 의미 설명
UNION 합집합 두 개의 데이터 집합이 있으면 각 집합 원소(SELECT 결과)를 모두 포함한 결과가 반환된다.
UNION ALL 합집합 UNION ALL은 중복된 항목도 모두 조회된다.
INTERSECT 교집합 데이터 집합에서 공통된 항목만 추출해 낸다.
MINUS 차집합 한 데이터 집합을 기준으로 다른 데이터 집합과 공통된 항목을 제외한 결과만 추출해 낸다.

 

데이터 집합이 대상이므로 집합 연산자를 사용할 때 데이터 집합의 수는 한 개 이상을 사용할 수 있다.
즉 여러 개의 SELECT문을 연결해 또 다른 하나의 쿼리를 만드는 역할을 하는 것이 집합 연산자이다. 

CREATE TABLE exp_goods_asia ( -- 한국과 일본의 10대 수출품 테이블
country VARCHAR2(10), -- 나라명
seq NUMBER, -- 번호
goods VARCHAR2(80) -- 상품명
);
 
INSERT INTO exp_goods_asia VALUES ('한국', 1, '원유제외 석유류');
INSERT INTO exp_goods_asia VALUES ('한국', 2, '자동차');
INSERT INTO exp_goods_asia VALUES ('한국', 3, '전자집적회로');
INSERT INTO exp_goods_asia VALUES ('한국', 4, '선박');
INSERT INTO exp_goods_asia VALUES ('한국', 5, 'LCD');
INSERT INTO exp_goods_asia VALUES ('한국', 6, '자동차부품');
INSERT INTO exp_goods_asia VALUES ('한국', 7, '휴대전화');
INSERT INTO exp_goods_asia VALUES ('한국', 8, '환식탄화수소');
INSERT INTO exp_goods_asia VALUES ('한국', 9, '무선송신기 디스플레이 부속품');
INSERT INTO exp_goods_asia VALUES ('한국', 10, '철 또는 비합금강');
 
INSERT INTO exp_goods_asia VALUES ('일본', 1, '자동차');
INSERT INTO exp_goods_asia VALUES ('일본', 2, '자동차부품');
INSERT INTO exp_goods_asia VALUES ('일본', 3, '전자집적회로');
INSERT INTO exp_goods_asia VALUES ('일본', 4, '선박');
INSERT INTO exp_goods_asia VALUES ('일본', 5, '반도체웨이퍼');
INSERT INTO exp_goods_asia VALUES ('일본', 6, '화물차');
INSERT INTO exp_goods_asia VALUES ('일본', 7, '원유제외 석유류');
INSERT INTO exp_goods_asia VALUES ('일본', 8, '건설기계');
INSERT INTO exp_goods_asia VALUES ('일본', 9, '다이오드, 트랜지스터');
INSERT INTO exp_goods_asia VALUES ('일본', 10, '기계류');
 
SELECT * FROM EXP_GOODS_ASIA;

 

① UNION

UNION은 합집합을 의미한다.
예를 들어, 두 개의 데이터 집합이 있으면 각 집합 원소(SELECT 결과)를 모두 포함한 결과가 반환된다.

: 국가에 상관없이 모든 수출품을 조회하는데, 단 자동차나 선박과 같이 두 국가가 겹치는 수출품목은 한번만 조회되도록 하려면 UNION(합집합 개념)을 사용한다.

SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='한국'
UNION
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='일본';
 

 

[예제] hr 스키마에 있는 JOB_HISTORY 테이블은 사원들의 업무 변경 이력을 나타내는 테이블이다. 

이 정보를 이용하여 모든 사원의 현재 및 이전의 업무 이력 정보를 출력하고자 한다. 중복된 사원정보가 있을 경우 한 번만 표시하여 출력하시오.

SELECT employee_id, job_id
FROM employees
UNION
SELECT employee_id, job_id
FROM job_history;

 

[예제] 위 결과를 이용하여 출력된 176번 사원의 업무 이력의 변경 날짜 이력을 조회하시오.

SELECT employee_id, job_id, NULL AS "Start Date", NULL AS "End Date"
FROM employees
WHERE employee_id = 176
UNION
SELECT employee_id, job_id, start_date, end_date
FROM job_history
WHERE employee_id = 176;

② UNION ALL

UNION ALL은 중복된 항목도 모두 조회된다는 점이다.

SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='한국'
UNION ALL
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='일본';

③ INTERSECT

INTERSECT는 합집합이 아닌 교집합을 의미한다. 즉 데이터 집합에서 공통된 항목만 추출해 낸다.

SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='한국'
INTERSECT
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='일본';

④ MINUS

MINUS는 차집합을 의미한다. 즉 한 데이터 집합을 기준으로 다른 데이터 집합과 공통된 항목을 제외한 결과만 추출해 낸다.

SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='한국'
MINUS
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='일본';

※ 집합 연산자의 제한 사항

- 집합 연산자로 연결되는 각 SELECT문의 SELECT 리스트의 개수와 데이터 타입은 일치해야 한다.

-- ORA-01789: 질의 블록은 부정확한 수의 결과 열을 가지고 있습니다.
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='한국'
UNION
SELECT SEQ, GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='일본';
-- ORA-01790: 대응하는 식과 같은 데이터 유형이어야 합니다
SELECT SEQ
FROM EXP_GOODS_ASIA
WHERE COUNTRY='한국'
UNION
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='일본';

- 집합 연산자로 SELECT문을 연결할 때 ORDER BY 절은 맨 마지막 문장에서만 사용할 수 있다.

-- ORA-00933: SQL 명령어가 올바르게 종료되지 않았습니다
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='한국'
ORDER BY GOODS
UNION
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='일본';
-- 위의 쿼리문을 수정하면
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='한국'
UNION
SELECT GOODS
FROM EXP_GOODS_ASIA
WHERE COUNTRY='일본'
ORDER BY GOODS;

 

'DB > SQL' 카테고리의 다른 글

Oracle 함수 모음  (0) 2022.04.11
SELECT문 절 / 연산자  (0) 2022.04.11
PreparedStatement  (0) 2022.04.06
PL / SQL  (0) 2022.04.03
시퀀스  (0) 2022.04.03