티스토리 뷰

1. 집합 연산자 ( Set Operator )

두 개 이상의 테이블에서 조인을 사용하지 않고 연관된 데이터를 조회하는 방법 중 하나.

집합 연산자는 여러 개의 질의의 결과를 연결하여 하나로 결합하는 방식을 사용한다.

 

∴ 집합 연산자는 2개 이상의 질의 결과를 하나의 결과로 만든다.

 

 

 

 

  [ 집합 연산자를 사용하는 경우 ]

(1) 서로 다른 테이블에서 유사한 형태의 결과를 반환하는 것을 하나의 결과로 합칠 때

(2) 동일 테이블에서 서로 다른 질의를 수행하여 결과를 합칠 때

(3) 튜닝 관점에서 실행 계획을 분리하고자 하는 목적일 때

 

 

  [ 집합 연산자를 사용하기 위한 제약조건 ]

(1) SELECT 절의 칼럼 수가 동일해야 한다.

(2) SELECT 절의 동일 위치에 존재하는 칼럼의 데이터 타입이 상호 호환 가능해야 한다.

 

제약조건을 만족하지 않을 경우, 데이터베이스가 오류를 반환한다.

 

 

 

 


집합 연산자의 종류

 

합집합 ( UNION / UNION ALL )

교집합 ( INTERSECT )

차집합 ( EXCEPT )

 

 

 


R1 과 R2 는 개별 결과 집합이다.

UNION ALL 을 제외한 다른 집합 연산자에서는 SQL 문의 결과 집합에서 먼저 중복된 건을 배제하는 작업을 수행한 후에 집합 연산을 적용한다.

집합 연산자의 연산

 

1. UNION 연산

합집합( R1∪R2 ) 의 결과는 { 1,2,3,4,5 } 이다.

 

2. UNION ALL 연산

중복에 대한 배제 없이 2개의 결과 집합을 단순히 합친 것과 동일하다.

{ 1,1,1,2,2,3,3,5,1,1,2,2,2,3,4 ] 가 결과가 된다.

 

3. INTERSECT 연산

교집합 ( R1∩R2 ) 의 결과는 { 1,2,3 } 이다.

 

4. EXCEPT 연산

차집합 ( R1 R2 ) 의 결과는 { 5 } 이다.

차집합 ( R2 R1 ) 의 결과는 반대로 { 4 } 이다.

 

 

 

 

 

 


>> PRACTICE

 

(1) 야구 선수들 중에서 소속이 삼성과 LG인 선수들에 대한 내용을 모두 보고싶다.

→ 소속이 삼성인 선수들의 집합과 LG인 선수들의 집합의 합집합

SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID = 'SAMSUNG'
UNION 
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID = 'LG';
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER 
WHERE TEAM_ID = 'SAMSUNG' OR TEAM_ID = 'LG';

 

 

(2) 소속이 삼성인 선수들과 포지션이 골키퍼인 선수들을 모두 보고싶다.

→ 소속이 삼성인 선수들의 집합과 야구 선수중 포지션이 골키퍼인 선수들의 집합의 합집합

SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID = 'SAMSUNG'
UNION
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE POSITION = 'GK';

여기서 UNION 이 아닌 UNION ALL 을 사용하면 결과가 달라진다. ( 중복된 결과를 제외시키지 않기 때문. )

 

 

 

(3) 야구 선수들의 포지션별 평균키와 팀별 평균키를 알고 싶다.

→ 야구선수의 포지션별 평균키에 대한 집합과 팀별 평균키에 대한 집합의 합집합

SELECT 'P'구분코드, POSITION 포지션, AVG(HEIGHT) 평균키
FROM PLAYER
GROUP BY POSITION
UNION
SELECT 'T'구분코드, TEAM_ID 팀명, AVG(HEIGHT) 평균키
FROM PLAYER
GROUP BY TEAM_ID
ORDER BY 1;

 

 

 

(4) 야구 선수 중 소속이 삼성이면서 포지션이 미드필더(MF) 가 아닌 선수들의 정보를 보고 싶다.

→ 소속이 삼성인 선수들의 집합과 야구 선수 중 포지션이 MF 인 선수들의 집합의 차집합

ORACLE
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션
FROM PLAYER
WHERE TEAM_ID = 'SAMSUNG'
MINUS ( 또는 SQL SERVER의 경우 EXCEPT)
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션
FROM PLAYER
WHERE POSITION = 'MF'
ORDER BY 1,2,3,4,5;

ORACLE 에서는 MINUS 를 사용했지만,

SQL SERVER 의 경우 EXCEPT 를 사용할 수 있다.

 

 

 

 

 

(5) 야구 선수 중 소속이 삼성이면서 포지션이 골키퍼(GK) 인 선수들의 정보를 보고 싶다.

→ 소속이 삼성인 선수들의 집합과 야구 선수 중 포지션이 GK 인 선수들의 집합의 교집합

SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션..
FROM PLAYER
WHERE TEAM_ID = 'SAMSUNG'
INTERSECT
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션..
FROM PLAYER
WHERE POSITION = 'GK'
ORDER BY 1,2,3,4,5;

INTERSECT 연산자는 EXISTS 또는 IN 서브쿼리를 이용한 SQL 문으로 변경할 수 있다.

 

 

 

 

 

 


 

댓글