[ SQLD : II. SQL 기본 및 활용] 2-2. 집합 연산자(Set Operator)

문지은·2023년 6월 7일
0

SQLD

목록 보기
21/30
post-thumbnail

[SQLD 시험 대비] 2과목. SQL 기본 및 활용 : 2장. SQL 활용 - 2. 집합 연산자(Set Operator)

집합 연산자(Set Operator)

  • 두 개 이상의 테이블에서 조인을 사용하지 않고 연관된 데이터를 조회하는 방법
  • 집합 연산자는 여러 개의 질의의 결과를 연결하여 하나로 결합하는 방식을 사용한다.
    • 즉, 집합 연산자는 2개 이상의 질의 결과를 하나의 결과로 만들어 준다.
  • 일반적으로 서로 다른 테이블에서 유사한 형태의 결과를 반환하는 것을 하나의 결과로 합치고자 할 때와 동일 테이블에서 서로 다른 질의를 수행하여 결과를 합치고자 할 때 집합 연산자를 사용한다.
  • 집합 연산자를 사용하기 위해서는 다음 제약조건을 만족해야 한다.
    • SELECT 절의 칼럼 수가 동일하고 SELECT 절의 동일 위치에 존재하는 칼럼의 데이터 타입이 상호 호환 가능(반드시 동일한 데이터 타입일 필요는 없음)해야 한다.
    • 그렇지 않으면 데이터베이스가 오류를 반환 한다.

집합 연산자의 종류

  • UNION
    • 여러 개의 SQL 문의 결과에 대한 합집합으로 결과에서 모든 중복된 행은 하나의 행으로 만든다.
  • UNION ALL
    • 여러 개의 SQL 문의 결과에 대한 합집합으로 중복된 행도 그대로 결과로 표시한다.
    • 즉, 단순히 결과만 합쳐놓은 것
    • 일반적으로 여러 질의 결과가 상호 배타적일때 많이 사용
    • 개별 SQL문의 결과가 서로 중복되지 않는 경우, UNION과 결과가 동일하다. (결과의 정렬 순서에는 차이가 있을 수 있음)
  • INTERSECT
    • 여러 개의 SQL문의 결과에 대한 교집합
    • 중복된 행은 하나의 행으로 만든다.
  • EXCEPT
    • 앞의 SQL문의 결과에서 뒤의 SQL문의 결과에 대한 차집합이다.
    • 중복된 행은 하나의 행으로 만든다. (일부 데이터베이스는 MINUS를 사용함)

집합 연산자를 사용한 SQL문

  • 집합 연산자를 사용하여 만들어지는 SQL문의 형태는 다음과 같다.
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문이라도 이용할 수 있다.
  • 집합 연산자는 여러 개의 SELECT문을 연결하는 것에 지나지 않는다.
  • ORDER BY는 집합 연산을 적용한 최종 결과에 대한 정렬 처리이므로 가장 마지막 줄에 한번만 기술한다.

예제 1

  • 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'
  • IN 또는 OR 연산자를 사용한 SQL문으로도 작성할 수 있다.
    • 출력되는 순서는 다를 수 있음
// OR 연산자 사용
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID = 'K02' OR TEAM_ID = 'K07';

// IN 연산자 사용
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER
WHERE TEAM_ID IN ('K02', 'K07');

예제 2

  • 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';

예제 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

  • K-리그 소속 선수를 중에서 소속이 삼성블루윙즈팀이면서 포지션이 미드필더(MF)가 선수들의 정보를 보고 싶다.
  • K-리그 소속 선수 중 소속이 삼성블루윙즈팀인 선수들의 집합과K-리그 소속 선수 중 포지션이 미드필더(MF))인 선수들의 집합의 차집합을 구하면 된다.
  • Oracle
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;
  • SQL Server에서는 MINUS 대신 EXCEPT를 사용할 수 있다.
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백 넘버, HEIGHT 키
FROM PLAYER
WHERE TEAM_ID = 'K02'
EXCEPT
SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백 넘버, HEIGHT 키
FROM PLAYER
WHERE POSITION = 'MF' 
ORDER BY 1, 2, 3, 4, 5;
  • 논리 연산자를 이용하여 동일한 결과 의 SQL문을 작성할 수 있다.
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;
  • NOT EXISTS 또는 NOT IN 서브쿼리를 이용한 SQL문으로도 변경 가능하다.
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

  • 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;
  • 논리 연산자만으로 결과가 동일한 SQL문을 작성할 수 있다.
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;
  • EXISTS 또는 IN 서브쿼리를 이용한 SQL문으로도 변경 가능하다.
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;
profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글