메뉴 건너뛰기

bysql.net

제2절_집합_연산자(SET_OPERATOR)

2011.10.11 20:42

실천하자 조회 수:13864

2. 집합 연산자(SET_OPERATOR)

- 연관된 데이터를 조회하는 방법 중 하나
- 여러 개의 질의의 결과를 연결하여 하나로 결합하는 방식 사용

   ☞ 즉, 집합 연산자는 2개 이상의 질의 결과를 하나의 결과로 만들어 준다. 

■ 일반적으로 집합 연산자를 사용하는 상황

  • 서로 다른 테이블에서 유사한 형태의 결과를 반환하는 것을 하나의 결과로 합치고자 할 때 사용
  • 동일 테이블에서 서로 다른 질의를 수행하여 결과를 합치고자 할 때 사용
  • 이외에도 튜닝관점에서 실행계획을 분리하고자 하는 목적으로도 사용

■ 집합 연산자를 사용하기 위한 제약조건 (조건을 지키지 않을 시 데이터베이스가 오류 반환)

  • SELECT 절의 칼럼 수가 동일
  • SELECT 절의 동일 위치에 존재하는 칼럼의 데이터 타입이 상호 호환 가능 (반드시 동일한 데이터 타입일 필요는 없음)

집합 연산자는 개별 SQL문의 결과 집합에 대해 합집합(UNION/UNION ALL), 교집합(INTERSECT), 차집합(EXCEPT)으로 집합간의 관계를 가지고 작업

가장 왼쪽에 존재하는 R1, R2는 각각의 SQL문을 실행해서 생성된 개별 결과 집합 의미

R1 = { 1, 2, 3, 5 }            R2 = { 1, 2, 3, 4 }


UNION ALL을 제외한 다른 집합 연산자에서는 

SQL문의 결과 집합에서 먼저 중복된 건을 배제하는 작업을 수행한 후에 집합 연산을 적용 (논리적인 관점의 처리임)

  • UNION 연산 : 합집합(R1 ∪ R2)의 결과는 {1, 2, 3, 4, 5}
  • UNION ALL 연산 : 중복에 대한 배제 없이 2개의 결과 집합을 단순히 합친 것과 동일 

              결과 {1, 1, 1, 2, 2, 3, 3, 5, 1, 1, 2, 2, 2, 3, 4}

  • INTERSECT 연산 : 교집합(R1 ∩ R2)의 결과는 {1, 2, 3}
  • EXCEPT 연산 : 차집합(R1 - R2)의 결과는 {5}

    ※ EXCEPT 연산에서는 순서 주의 : 차집합(R2 - R1)의 결과는 {4}


▼ 문법

SELECT 칼럼명1, 칼럼명2, ... 

FROM 테이블명1 

WHERE 조건식 ] [[GROUP BY 칼럼(Column)이나 표현식 [HAVING 그룹조건식 ] ] 

집합 연산자 

SELECT 칼럼명1, 칼럼명2, ... 

FROM 테이블명2 

WHERE 조건식 ] [[GROUP BY 칼럼(Column)이나 표현식 [HAVING 그룹조건식 ] ] 

ORDER BY 1, 2 [ASC 또는 DESC ] ; 


    ▼ 예제

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는 집합 연산을 적용한 최종 결과에 대한 정렬 처리이므로 가장 마지막 줄에 한번만 기술


■ 예제 1 - 'UNION' vs 'OR 연산자' / 'IN List'

 질문 

 K-리그 소속 선수들 중에서 소속이 삼성블루윙즈팀인 선수들과                                                 

 전남드레곤즈팀인 선수들에 대한 내용을 모두 보고 싶다. 

집합

 K-리그 소속 선수 중 소속이 삼성블루윙즈팀인 선수들의 집합과

 K-리그 소속 선수 중 소속이 전남드레곤즈팀인 선수들의 집합의 합집합

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02'

 UNION

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K07'

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02' OR TEAM_ID = 'K07'

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID IN ('K02', 'K07')



■ 예제 2 - 'UNION' vs 'UNION ALL'

 질문 

 K-리그 소속 선수들 중에서 소속이 삼성블루윙즈팀인 선수들과                                                 

 포지션이 골키퍼(GK)인 선수들을 모두 보고 싶다.

집합

 K-리그 소속 선수 중 소속이 삼성블루윙즈팀인 선수들의 집합과

 K-리그 소속 선수 중 포지션이 골키퍼(GK)인 선수들의 집합의 합집합

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02'

 UNION

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE POSITION = 'GK'

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02'

 UNION ALL

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE POSITION = 'GK'



■ 예제 3 - 각 집합의 구분

질문

 K-리그 소속 선수들에 대한 정보 중에서 포지션별 평균키와 팀별 평균키를 알고 싶다.

 집합 

 K-리그 소속 선수 중 포지션별 평균키에 대한 집합과 K-리그 소속 선수 중 팀별 평균키에 대한 집합의 합집합     

쿼리

 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 - 'MINUS'('EXCEPT') vs '<>' / 'NOT EXISTS 서브쿼리' / 'NOT IN 서브쿼리'

질문

 K-리그 소속 선수를 중에서 소속이 삼성블루윙즈팀이면서

 포지션이 미드필더(MF)가 아닌 선수들의 정보를 보고 싶다.  

 집합 

 K-리그 소속 선수 중 소속이 삼성블루윙즈팀인 선수들의 집합과

 K-리그 소속 선수 중 포지션이 미드필더(MF)인 선수들의 집합의 차집합                                         

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02'

 MINUS

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE POSITION = 'MF'

 ORDER BY 1, 2, 3, 4, 5

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02' AND POSITION <> 'MF'

 ORDER BY 1, 2, 3, 4, 5

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER X

 WHERE X.TEAM_ID = 'K02' AND

        NOT EXISTS (SELECT 1 FROM PLAYER Y WHERE Y.PLAYER_ID = X.PLAYER_ID AND POSITION = 'MF')

 ORDER BY 1, 2, 3, 4, 5

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02' AND

        PLAYER_ID NOT IN (SELECT PLAYER_ID FROM PLAYER WHERE POSITION = 'MF')

 ORDER BY 1, 2, 3, 4, 5



■ 예제 5 - 'INTERSECT' vs 'AND =' / 'EXISTS 서브쿼리' / 'IN List 서브쿼리'

질문

 K-리그 소속 선수들 중에서 소속이 삼성블루윙즈팀이면서 포지션이 골키퍼(GK)인 선수들의 정보를 보고 싶다.     

집합

 K-리그 소속 선수 중 소속이 삼성블루윙즈팀인 선수들의 집합과

 K-리그 소속 선수 중 포지션이 골키퍼(GK)인 선수들의 집합의 교집합

 쿼리 

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02'

 INTERSECT

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE POSITION = 'GK'

 ORDER BY 1, 2, 3, 4, 5

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02' AND POSITION = 'GK'

 ORDER BY 1, 2, 3, 4, 5

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER X

 WHERE X.TEAM_ID = 'K02' AND

        EXISTS (SELECT 1 FROM PLAYER Y WHERE Y.PLAYER_ID = X.PLAYER_ID AND Y.POSITION = 'GK')

 ORDER BY 1, 2, 3, 4, 5

비교

쿼리

 SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키

 FROM PLAYER

 WHERE TEAM_ID = 'K02' AND

        PLAYER_ID IN (SELECT PLAYER_ID FROM PLAYER WHERE POSITION = 'GK')

 ORDER BY 1, 2, 3, 4, 5



※ 자료출처 : DBguide.Net

http://www.dbguide.net/db.db?cmd=view&boardUid=148199&boardConfigUid=9&categoryUid=216&boardIdx=135&boardStep=1


  • SQL 개발자 자격증 (bysql.net 2011년 2차 스터디)
  • 작성자: 위충환 (실천하자)
  • 최초작성일: 2011년 10월 11 일
  • 본문서는 bysql.net 스터디 결과입니다 .본 문서를 인용하실때는 출처를 밝혀주세요. http://www.bysql.net
  • 문서의 잘못된 점이나 질문사항은 본 문서에 댓글로 남겨주세요. ^^

번호 제목 글쓴이 날짜 조회 수
47 5 연습문제 RYUM 2014.08.07 9534
46 5 연습문제 RYUM 2014.08.07 7509
45 5_장_요약 balto 2011.11.16 6977
44 SQL 문제 [2] file balto 2011.11.15 26818
43 제3절_조인_수행_원리 노랑배 2011.11.10 6378
42 제1절_옵티마이저와_실행계획 실천하자 2011.11.08 5274
41 제1절 옵티마이저와 실행계획 실천하자 2011.11.07 5989
40 4_연습문제 monsterRachel 2011.11.03 10834
39 4_장_요약 suspace 2011.11.03 6423
38 제6절_윈도우_함수(WINDOW_FUNCTION) suspace 2011.10.27 20530
37 제8절_절차형_SQL monsterRachel 2011.10.27 8682
36 제7절_DCL(DATA_CONTROL_LANGUAGE) file DB지기 2011.10.26 8522
35 제2절_인덱스_기본4 balto 2011.10.24 7707
34 .. balto 2011.10.14 4840
33 제1절_표준_조인(STANDARD_JOIN) 노랑배 2011.10.13 15659
32 3_연습문제 DB지기 2011.10.13 7076
31 3_장_요약 file DB지기 2011.10.13 6066
30 제3절_계층형_질의와_셀프_조인 [1] 실천하자 2011.10.12 11483
» 제2절_집합_연산자(SET_OPERATOR) [1] 실천하자 2011.10.11 13864
28 제5절_그룹_함수(GROUP_FUNCTION) file balto 2011.10.08 11424