쌓고 쌓다

[Oracle] 집합 연사자 (UNION, UNION ALL, MINUS, INTERSECT) 본문

프로그래밍/SQL

[Oracle] 집합 연사자 (UNION, UNION ALL, MINUS, INTERSECT)

승민아 2022. 10. 2. 02:07

집합 연산자

테이블을 구성하는 행집합에 대해 테이블의 부분 집합으 결과로 반환하는 연산자

집합 연산의 대상이 되는 두 테이블의 칼럼 수가 같고, 대응되는 칼럼끼리 데이터 타입이 동일하면 합병 가능하다.

 

집합 연산자 의미
UNION 두 집합에 대해 중복되는 행을 제외한 합집합
UNION ALL 두 집합에 대해 중복되는 행을 포함한 합집합
MINUS 두 집합간의 차집합
INTERSECT 두 집합간의 교집합

 

문법

SELECT 명령문1
[UNION | UNION ALL | INTERSECT | MINUS]
SELECT 명령문2;

 

집합 연산을 위한 테이블 생성

1학년이면서 몸무게가 70이상인 학생의 집합 : stud_heavy

1학년이면서 101번 학과인 학생의 집합 : stud_101

두 테이블을 생성한다.

 

테이블 생성

CREATE TABLE stud_heavy
AS SELECT *
FROM student
WHERE weight >= 70 AND grade=1; -- 집합 A

CREATE TABLE stud_101
AS SELECT *
FROM student
WHERE deptno=101 AND grade=1; -- 집합 B

합병 불가능한 경우

SELECT studno, name
    FROM stud_heavy
UNION
SELECT studno, name, grade
    FROM stud_101;

-> 열의 수가 다르므로 에러!

 

UNION, UNION ALL 비교

 

1. UNION

SELECT studno, name
    FROM stud_heavy
UNION
SELECT studno, name
    FROM stud_101;

-> 중복 행을 제외하고 출력

 

2. UNION ALL

SELECT studno, name
    FROM stud_heavy
UNION ALL
SELECT studno, name
    FROM stud_101;

-> 중복된 행을 포함하여 출력

 

EX) 학생 테이블과 교수 테이블에서 101번 학과에 소속된 교수와 학생의 번호와 이름을 출력

SELECT studno, name
    FROM student
    WHERE deptno=101
UNION ALL
SELECT profno, name
    FROM professor
    WHERE deptno=101;

 

EX) 아래와 같이 출력해보자.

SELECT profno "번호", name "성명", deptno "학과번호", '교수' "구분"
    FROM professor
UNION
SELECT studno, name, deptno, '학생'
    FROM student;

 

INTERSECT 연산

두 개의 테이블에 모두 속하는 행 집합을 반환한다.

 

1) stud_heavy, stud_101을 이용해 INTERSECT 연산을 수행하여

101번 학과의 1학년중에서 몸무게가 70 이상인 학생

SELECT studno, name
    FROM stud_101
INTERSECT
SELECT studno, name
    FROM stud_heavy;

 

MINUS 연산

테이블 A, B에서 A테이블에 속하지만 B테이블에는 속하지 않는 행 집합을 결과로 반환

차집합을 의미함.

 

1) stud_heavy, stud_101을 이용해 MINUS 연산을 써서

1학년중에서 몸무게가 70이상인 학생을 출력하되

101번 학과에 소속된 학생을 제외하고 출력

SELECT studno, name
    FROM stud_heavy
MINUS
SELECT studno, name
    FROM stud_101;

 

+ 테이블의 순서를 바꾸면?

SELECT studno, name
    FROM stud_101
MINUS
SELECT studno, name
    FROM stud_heavy;

 

101번 학과 학생중에서 몸무게가 70이상인 학생을 제외하고 출력한다.

 

 

1) 소속 교수는 있으나, 소속학생이 없는 학과 번호를 출력.

SELECT deptno
    FROM professor
MINUS
SELECT deptno
    FROM student;

-> 교수의 소속 학과들을 뽑아와 학생들의 학과를 빼버리면 교수는 있으나 학생이 없는 학과 번호만 남는다.

 

2) 소속교수와 소속학생이 모두 있는 학과 번호를 출력.

SELECT deptno
    FROM professor
INTERSECT
SELECT deptno
    FROM student;

-> 교수의 학과번호와 학생들의 학과번호의 교집합을 하면 교수, 학생 모두 있는 학과번호만 남는다.

Comments