[SQLD] 2과목 SQL 기본및 활용 - 1장 9절 JOIN


1. 조인의 개요

- 두 개 이상의 테이블 들을 연결 또는 결합하여 데이터를 출력하는 것을 JOIN이라고 한다.

- 일반적인 경우 행들은 PK나 FK값의 연관만으로 JOIN 성립이 가능하다.

- 선수라는 테이블과 팀이라는 테이블이 있는 경우 선수 테이블을 기준으로 필요한 데이터를 검색하고 이 데이터와 연관된 팀 테이블의 특정 행을 찾아오는 과정이 JOIN을 이용하여 데이터를 검색하는 과정으로 볼 수 있다.

- FROM 절에 여러개의 테이블을 나열하더라도 SQL에서 처리할 때는 단 두 개의 집합 간에만 조인이 일어난다. 

이때 테이블의 조인 순서는 옵티마이저에 의해 결정된다.

(FROM 절에 A, B, C 세 테이블이 나열되었 더라도 특정 2개의 테이블만 먼저 조인 처리되고, 나머지 두개의 테이블이 조인되어 처리된 새로운 데이터 집합과 남은 한 개의 테이블이 다음 차례로 조인된다.)


2. EQUI 조인

- EQUI 조인은 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하는 경우에 사용되는 방법으로

PK - FK 관계를 기반으로 한다. 

(일반적으로 테이블 설계시에 나타난 PK - FK의 관계를 이용하는 것이지 반드시 PK - FK 의 관계로만 EQUI JOIN이 발생하는 것은 아니다.)

- 이 기능은 계층형이나 망형 데이터베이스와 비교하여 관계형 데이터베이스의 큰 장점이다.

- JOIN 조건은 WHERE 절에 기술하게 되는데 " =  " 연산자를 사용해서 표현한다.

- 조인조건에 맞는 데이터만 출력하는 INNER JOIN에 참여하는 대상 테이블이 N개라고 했을 때 N개의 테이블로부터 필요한 데이터를 조회하기 위해 필요한 JOIN 조건은 대상 테이블의 개수에서 하나를 뺀 N-1개 이상 필요하다.

(EX. 나열된 테이블이 2개일 경우 1개이상 조건 필요하며, 3개일 경우 2개이상 조건이 필요함.)

SELECT 테이블1.칼럼명, 테이블2,칼럼명

FROM 테이블1, 테이블2

WHERE 테이블1.칼럼명 = 테이블2.칼럼명2;

* WHERE절에 JOIN 조건을 넣는다.


- ANSI/ISO SQL 표준방법으로 표기.

SELECT 테이블1.칼럼명, 테이블2.칼럼명 .. .. .

FRON 테이블1 INNER JOIN 테이블2

WHERE 테이블1.칼럼명1 = 테이블2.칼럼명2 ;


EX) 선수 테이블과 팀 테이블에서 선수 이름과 소속된 팀의 이름을 출력하시오.


A. 

SELECT PLAYER.PLAYERNAME, TEAM.TEAMNAME

FROM PLAYER, TEAM

WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID


* ANSI/ISO SQL 표준방법 표기가능

SELECT PLAYER.PLAYERNAME, TEAM.TEAMNAME

FROM PLAYER INNER JOIN TEAM

ON PLAYER.TEAM_ID INNSER JOIN TEAM.TEAM_ID



- 테스트 가능한 EMP 테이블로 실행
각 사원별 부서이름을 출력하라.

1.

SELECT EMP.ENAME, DEPT.DNAME

FROM EMP, DEPT

WHERE EMP.DEPTNO = DEPT.DEPTNO ;


2.ANSI

SELECT EMP.ENAME, DEPT.DNAME

FROM EMP INNER JOIN DEPT

ON EMP.DEPTNO = DEPT.DEPTNO ;


ENAME   DNAME

---------- --------------

SMITH   RESEARCH

ALLEN   SALES

WARD   SALES

JONES   RESEARCH

MARTIN   SALES

BLAKE   SALES

CLARK   ACCOUNTING

SCOTT   RESEARCH

KING   ACCOUNTING

TURNER   SALES

ADAMS   RESEARCH

JAMES   SALES

FORD   RESEARCH

 

MILLER   ACCOUNTING

 



 가. 선수 - 팀 EQUI JOIN 사례

- 선수 테이블과 팀 테이블에서 K리그 소속 선수들의 이름,백넘버와 그 선수가 소속되어 있는 팀명 및 연고지를 알고싶은경우?

- 선수테이블의 소속코드를 기준으로 팀 테이블에 들어있는 데이터를 재배치 하여 결과를 얻게된다.

- 테이블 명을 앞에 쓸 경우 가독성이 떨어질 수 있으므로 ALIAS 를 주로 사용한다.


A. 

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER, TEAM

WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID


A. ANSI 

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER INNER JOIN TEAM 

ON PLAYER.TEAM_ID = TEAM.TEAM_ID


A. ALIAS 적용

SELECT P.PLAYER_NAME, P.BACK_NO, T.TEAM_NAME, T.REGION_NAME

FROM PLAYER P, TEAM T

WHERE P.TEAM_ID = T.TEAM_ID


SELECT P.PLAYER_NAME, P.BACK_NO, T.TEAM_NAME, T.REGION_NAME

FROM PLAYER P INNER JOIN TEAM T

WHERE P.TEAM_ID = T.TEAM_ID


나. 선수 - 팀 WHERE 절 검색 조건 사례

- WHERE절에 JOIN 조건 이외이 검색 조건에 대한 제한 조건을 덧붙여 사용할 수 있다.

- EQUI JOIN의 최소한의 연관 관계를 위해서 테이블 개수 - 1 개의 JOIN 조건을 WHERE 절에 명시하고, 부수적인 제한조건을 논리 연산자를 통하여 추가로 입력하는것이 가능하다.

- JOIN 조건을 기술 할 때 만약 테이블에 대한 ALIAS를 적용해서 SQL문장을 작성했을 경우, WHERE절과 SELECT 절에는 테이블명이 아닌 테이블에 대한 ALIAS를 사용해야한다.  => 에러발생


SELECT PLAYER.PLAYER_NAME, P.BACK_NO, T.TEAM_NAME, T.REGION_NAME

FROM PLAYER P , TEAM T

WHERE P.TEAM_ID = T.TEAM_ID

AND PLAYER.POSITION='GK'
ORDER BY PLAYER.BACK_NO;


Q. 위에 수행한 쿼리에 포지션이 골키퍼인 선수들에 대한 데이터반 백넘버순으로 출력.


A.

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER, TEAM

WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID

AND PLAYER.POSITION='GK'
ORDER BY PLAYER.BACK_NO;



다. 팀 - 구장 EQUI 조인 사례


Q. 팀 테이블과 구장 테이블의 관계를 이용하여 소속팀이 가지고있는 전용구장의 정보를 팀 정보와 함께 출력


SELECT T.REGEION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, S.SEATCOUNT

FROM TEAM T, STADIUM S

WHERE T.STADIUM_ID = S.STADIUM_ID;


* 중복이 되지 않는 컬럼에 대해서는 테이블 명과 ALIAS를 쓰지 않아도 되며, 같은 이름을 가진 중복 칼럼의 경우 테이블명이나 ALIAS 가 필수이다.


SELECT REGEION_NAME, TEAM_NAME, T.STADIUM_ID, STADIUM_NAME, SEATCOUNT

FROM TEAM T, STADIUM S

WHERE T.STADIUM_ID = S.STADIUM_ID;

=> 가능.

3. NON EQUI
-  NON EQUI 조인은 두 테이블간에 칼럼 들이 서로 정확하게 일치하지 않는 경우에 사용된다.
" = " 연산자가 아닌 BEETWEEN, >, >=, <, <= 연산자 등을 사용하여 조인한다.
- 두개의 테이블이 PK - FK로 연관관계를 가지거나 논리적으로 같은값이 존재하는 경우 EQUI 조인을 수행하지만, 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우에 EQUI 조인을 사용할 수 없다. 이런 경우에 Non EQUI JOIN을 시도할 수 있으나 데이터 모델에 따라서 NON EQUI JOIN이 불가능한 경우도 있다.
(PLAYER 모델에서는 할 수 없음.)

- NON EQUI JOIN의 대략적인 형태

SELECT 테이블1.칼럼1, 테이블2.칼럼2 . .. ...

FROM 테이블1, 테이블2

WHERE 테이블1.칼럼명1 BETWEEN 테이블2.칼럼명1 AND 테이블2.칼럼명2

* BETWEEN a AND b 조건은 Non EQUI JOIN의 한 사례이다.


ex) EMP 테이블과 SAL테이블을 이용하여 어떤사원의 급여가 어느 등급에 속하는지 알고 싶다는 요구사항에 대한 non equi join

A.

SELECT E.ENAME, E.JOB, E.SAL, S.GRADE

FROM EMP E, SALGRADE S

WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL ;




4. 3개 이상 테이블 조인

- 선수들별로 홈그라운드 경기장이 어디인지 출력하고 싶다고 했을 때, 선수테이블과 운동장 테이블은 서로 관련이 없으므로 중간에 팀 테이블이라는 서로 연관관계가 있는 테이블을 추가해서 세 개의 테이블을 JOIN 해야만 원하는 데이터를 얻을 수 있다.


EX)

SELECT P.PLAYER_NAME, P.POSITION, T.REGION_NAME, T.TEA_NAME, S.STADIUM_NAME

FROM PLAYER P, TEAM T, STADIUM S

WHERE P.TEAM_ID = T.TEAM_ID

      AND T.STADIUM_ID = S.STADIUM_ID

ORDER BY 선수명;



* INNER JOIN 

SELECT P.PLAYER_NAME, P.POSITION, T.REGION_NAME, T.TEA_NAME, S.STADIUM_NAME

FROM PLAYER P INNER JOIN  TEAM T ON P.TEAM_ID = T.TEAM_ID

            INNER JOIN STADIUM S ON  T.STADIUM_ID = S.STADIUM_ID

ORDER BY 선수명;