반응형

❏ 집합 연산자 (STANDARD JOIN)

 

 - 두 개 이상의 테이블에서 JOIN 을 사용하지 않고도 연관된 데이터를 조회할 수 있다고..?!

 - 집합 연산자를 이용하는 방법이다! 여러개의 질의의 결과를 연결하여 하나로 결합하는 방식.

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

   

 

합집합 (UNION/UNION ALL)

교집합 (INTERSECT)

차집합 (EXCEPT) 

 

 

 

 

select 칼럼1, 칼럼2, ...
from 테이블1
where 
group by
having


<집합연산자>


select 칼럼1, 칼럼2, ...
from 테이블2
where
group by
having
order by 1, 2;

아 이렇게 select 덩어리가 2개 이상 인 거의 집합연산자 로 연결시키는거구나. 그래서 아까 처음에 select 절에서 

칼럼의 수가 동일해야 한다는게 이 select 덩어리들의 칼럼 명시한 수가 똑같아야 한다.

예제 풀어보자

 

(1) K-리그 소속 선수들 중에서 소속이 삼성블루윙즈 인 선수들과 전남드래곤즈 인 선수들에 대한 내용을 모두 보고 싶다

  → K-리그 소속 선수 중 삼성블루윙즈 팀의 집합 < 합집합(UNION) > 전남드래곤즈 팀의 집합

 

 

이 합집합 UNION 은 where 절에 IN 또는 OR 연산자로도 변환이 가능하다.. 

다만 결과의 표시 순서가 달라질 수 있지만 집합이 다르다고는 할 수는 없다.

 

where TEAM_ID = 'K02' or TEAM_ID ='K07';
where TEAM_ID IN ('K02','K07');

 

UNION 과 UNION ALL 은 확실히 다르다.

 

UNION 은 결과에서 중복을 제거하지만, UNION ALL 은 각각의 질의 결과를 그냥 단순히 결합시키고 중복도 그냥 하기 때문에...

 

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

 → K-리그 소속 선수 중 포지션별 평균키 집합  UNION  팀별 평균키 집합

 

~~~별 은 GROUP 을 지었다는 뜻.

 

 

 

 

 

구분코드, 포지션, 평균키 라는 칼럼명의 결과가 나왔다.  

 

SQL 문에서 첫번쨰에는 구분코드/포지션/평균키, 두번째에는 구분코드/팀명/평균키 로 했는데..

 

첫 번째 SQL 문에서 사용된 칼럼명 이 적용된다!

 

그룹함수도 집합연산자 에서 사용이 가능 하고

 

실제로 테이블에는 존재하지 않지만 'P' as 구분코드 를 추가 하였다.

 

목적을 위해 select 절에 임의의 칼럼을 추가하는 것은 모든 SQL 문에서 적용 가능하다. (지금알았음)

 

 

(3) K-리그 소속 선수들 중에서 소속이 삼성블루윙즈팀이면서 포지션이 미드필더가 아닌 선수들의 정보

 → K-리그 소속 선수 중 삼성블루윙즈 팀인 선수들의 집합 MINUS 포지션이 미드필더인 집합

 

맨 위의 INTERSECT 그림을 보면 이해가 빠르다. 삼성블루윙즈 이면서 미드필더 가 '아닌' 집합.

 

 

 

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

 

MINUS 는 NOT EXISTS  /  NOT IN 서브쿼리를 이용한 SQL 문으로도 변경 가능하다 (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.PLATER_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;

 

또 이렇게도 사용가능하다

 

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;

 

<> 이나 뭐 != 이나 같다. 

 

 

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

 → 소속이 삼성블루윙즈 집합 INTERSECT 포지션이 골키퍼 집합

 

간단할거같다.

 

 

 

 

간단하다.

 

 

 

도 결과가 똑같다. 

 

또, 아까 MINUS 에서 썼던거랑 반대로 EXISTS , IN 서브쿼리로도 바꿀 수 있다.

 

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.PLATER_ID = X.PLAYER_ID AND 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;
반응형
글이 도움이 되셨다면 공감과 광고 클릭 한번 부탁드려요! :)
감사합니다 ✨