본문 바로가기

SQLD

[SQLD : Ⅳ. SQL 활용] 2. 집합 연산자

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

 - 기존의 조인은 FROM 절에 검색하고자  하는 테이블 나열, WHERE 절에서 조건을 기술

 - 집합 연산자는 여러 질의의 결과를 연결하여 하나로 결합하는 방식 사용

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;

1) K-리그 소속 선수들 중에서 소속이 삼성블루윙즈팀인 선수들과전남드레곤즈팀인 선수들에 대한 내용

1) 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) K-리그 소속 선수들 중에서 소속이 삼성블루윙즈팀인 선수들과 포지션이 골키퍼(GK)인 선수

2) 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' OR POSITION = 'GK';

두 번째 질문에 대한 SQL문에서 UNION이라는 집합 연산자 대신에 UNION ALL이라는 집합 연산자를 사용

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

UNION과 UNION ALL의 결과는 달라진다.

UNION ALL에서 중복된 결과들을 확인해 보고자 할 때는 ORDER BY절을 사용하면 용이하다.

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' 
          ORDER BY 1, 2, 3, 4, 5;

3) K-리그 소속 선수들에 대한 정보 중에서 포지션별 평균키와 팀별 평균키

3) 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)가 선수

4) 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;

SQL Server에서는 MINUS대신 EXCEPT를 사용할 수 있다.

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;

MINUS 연산자는 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)인 선수

5) 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;

 INTERSECT 연산자를 사용하지 않고도 논리 연산자만 사용

SELECT TEAM_ID 팀코드, PLAYER_NAME 선수명, POSITION 포지션, BACK_NO 백넘버, HEIGHT 키 
FROM PLAYER 
WHERE TEAM_ID = 'K02' AND POSITION = 'GK' O
RDER BY 1, 2, 3, 4, 5;

INTERSECT 연산자는 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;