최보름달

[SQL] 집합 연산자 (UNION, UNION ALL, INTERSECT, EXCEPT, MINUS) 본문

문송한 회사생활/SQL 공부

[SQL] 집합 연산자 (UNION, UNION ALL, INTERSECT, EXCEPT, MINUS)

PieMoon 2020. 8. 15. 17:08

JOIN을 이용하지 않고 연관된 데이터를 조회하는 방법이 있다. 

집합 엽산자(Set Operator)를 사용하는 것이다. 

집합 연산자는 여러 개의 질의 결과를 나열해서 결합하는 방식이다. 

서로 다른 테이블에서 유사한 형태의 결과를 반환하는 것을 하나의 결과로 합칠 때 사용할 수 있다. 

집합 연산자를 사용하려면 SELECT 절의 컬럼 수가 동일하고 데이터 타입이 호환 가능해야 한다. 

 

집합 연산자 종류

UNION : 합집합. 모든 중복된 행을 하나로 합친다. 

UNION ALL : 합집합이지만, 중복된 행도 그대로 결과로 표시된다. 

INTERSECT : 교집합. 

EXCEPT : 차집합. (MINUS를 사용하기도 한다)

 

 

집합 연산자의 SQL문 형태

SELECT  컬럼명1, 컬럼명2, ...
FROM    테이블1

집합 연산자 

SELECT  컬럼명1, 컬럼명2, ...
FROM    테이블2 ;

 

예시

SELECT   PLAYER_NAME 선수명, BACK_NO 백넘버
FROM     PLAYER
WHERE    TEAM_ID = 'K02'

UNION

SELECT   PLAYER_NAME 선수명, BACK_NO 백넘버
FROM     PLAYER
WHERE    TEAM_ID = 'K07' 
ORDER BY 1 ;

 

집합 연산자는 제약조건만 만족한다면 어떤 형태의 SELECT 문이라도 이용할 수 있다. 

집합 연산자는 여러 개의 SELECT 문을 연결하는 것에 지나지 않는다. 

ORDER BY 최종 결과에 대한 정렬 처리이므로 마지막 줄에 한번만 기술한다. 

 

UNION의 경우 IN 또는 OR  연산자로 대체해도 된다. 

하지만, IN, OR를 사용하게 되면 결과 표시 순서가 달라질 수 있으므로 ORDER BY를 이용해서 정렬 순서를 정의해야 한다. 

 

팀이 K02  이면서 포지션이 골키퍼인 선수를 출력하라. 

SELECT   PLAYER_NAME 선수명, BACK_NO 백넘버, POSITION 포지션
FROM     PLAYER
WHERE    TEAM_ID = 'K02'

UNION

SELECT   PLAYER_NAME 선수명, BACK_NO 백넘버, POSITION 포지션
FROM     PLAYER
WHERE    POSITION = 'GK' ;

-> 이 결과의 행의 갯수는 88개 이다. 

SELECT   PLAYER_NAME 선수명, BACK_NO 백넘버, POSITION 포지션
FROM     PLAYER
WHERE    TEAM_IN = 'K02'

UNION ALL

SELECT   PLAYER_NAME 선수명, BACK_NO 백넘버, POSITION 포지션
FROM     PLAYER
WHERE    POSITION = 'GK' ;

-> 이 결과의 행의 갯수는 92개 이다. 

 

UNION은 결과에서 중복이 존재할 경우 중복을 제외시키지만, UNION ALL 은 중복을 제외하지 않으므로 갯수 차이가 난다.

 

포지션별 평균 키와 팀별 평균키를 구하라.

SELECT  'P'구분코드, POSOTION 포지션, AVG(HEIGHT) 평균키
FROM     PLAYER
GROUP BY POSITION 

UNION

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

그룹함수에서 집합 연산자를 사용하는 것이 가능하다.

실제 테이블에는 존재하지 않지만, 결과 행을 구분하기 위해 SELECT 절에 '구분코드'를 추가할 수도 있다.

SELECT 절에 임의의 컬럼을 추가하는 것은 다른 모든 SQL문에서 적용 가능하다.

 

집합 연산자의 결과를 표시할 때에는 첫번째 SQL 문에서 사용된 HEADING (ALIAS)이 적용된다.

첫번째 SELECT 절에서는 '포지션', 두번째 SELECT 절에서는 '팀명' 이 사용되었는데 

결과에는 '포지션' 으로 표시된다. 

 

 

K02 팀이면서 미드필더가 아닌 선수들의 차집합을 구하라. 

SELECT   PLAYER_NAME 선수명, BACK_NO 백넘버, POSITION 포지션
FROM     PLAYER
WHERE    TEAM_ID = 'K02'

MINUS

SELECT   PLAYER_NAME 선수명, BACK_NO 백넘버, POSITION 포지션
FROM     PLAYER
WHERE    POSITION = 'MF' 
ORDER BY 1, 2, 3;


-- SQL SERVER 에서는 EXCEPT를 사용한다. 

차집합은 앞에서 뒤의 결과를 빼는 것이다. 

 

 

 

 

kdata 한국데이터진흥원에서 출간한 SQL 전문가 가이드 2013 Edition을 요약했습니다. 

 

'문송한 회사생활 > SQL 공부' 카테고리의 다른 글

[SQL] 셀프 조인(SELF JOIN)  (0) 2020.08.16
[SQL] 오라클 계층형 질의 (Hierarchical Query)  (0) 2020.08.16
[SQL] OUTER JOIN (LEFT, RIGHT, FULL)  (0) 2020.08.15
[SQL] CROSS JOIN  (0) 2020.08.15
[SQL] USING, ON 조건절  (0) 2020.08.15