티스토리 뷰

1. JOIN 개요

▷ 조인 ( JOIN )

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

      일반적으로 사용되는 SQL 문장의 상당수가 JOIN 이다. (중요성)

      JOIN 은 관계형 데이터베이스의 가장 큰 장점이고 대표적인 핵심 기능이다.

 

      PK, FK 의 관계가 없어도 논리적인 값들의 연관만으로 JOIN 성립이 가능하다.

 

 

   < JOIN 주의점 >

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

      FROM 절에 A, B, C 테이블이 나열되었더라도 특정 2개의 테이블만 먼저 JOIN 처리 되고,

      2개의 테이블이 조인되어서 처리된 새로운 데이터 집합과 남은 한 개의 테이블이 다음 JOIN 된다.

 

 

 

 

 

 

테이블 간의 관계도

 

 

 

 

 

 

 

 

 

 


2. EQUI JOIN

▷ EQUI ( 등가 ) JOIN

    : 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치할 경우 사용한다.

      대부분 PK ↔ FK 의 관계를 기반으로 한다.

      ( 반드시 PK ↔ FK 의 관계로 성립하는 것은 아니다 )

      계층형 ( Hierarchical ) 이나 망형 ( Network ) 데이터베이스와 비교해서 관계형 데이터베이스의 큰 장점이다.

      

 

   < JOIN 조건 >

      (1) WHERE 절에 기술한다. " = " 연산자를 사용해서 표현한다.

      (2) 테이블에 ALIAS 를 적용했다면, WHERE 절과 SELECT 절에는 테이블명이 아닌 ALIAS 를 사용해야 한다.

          ( 권장 사항은 아니다 )

 

 

 

 

* EQUI JOIN 형태

SELECT 테이블1.칼럼명, 테이블2.칼렴명, ... FROM 테이블1, 테이블2
WHERE 테이블1.칼럼명 = 테이블2.칼럼명;

WHERE 절에 JOIN 조건을 넣는다.

 

 

 

 ** ANSI / ISO SQL 표준방식

SELECT 테이블1.칼럼명, 테이블2.칼럼명, ... FROM 테이블1
INNER JOIN 테이블2 ON 테이블1.칼럼명 = 테이블2.칼럼명;

ON 절에 JOIN 조건을 넣는다.

 

 

 

 

 


(예제)

 

(1) 선수 테이블과 팀 테이블에서 선수 이름과 소속된 팀의 이름을 출력한다.

SELECT PLAYER.PLAYER_NAME 선수명, TEAM.TEAM_NAME 소속팀명 FROM PLAYER, TEAM 
WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID;

SELECT PLAYER.PLAYER_NAME 선수명, TEAM.TEAM_NAME 소속팀명 FROM PLAYER
INNER JOIN TEAM ON PLAYER_TEAM_ID = TEAM.TEAM_ID;

 " 테이블명.칼럼명 "

(1) 모든 테이블에 칼럼들이 유일한 이름이면 상관 없다.

하지만, JOIN 에 사용되는 두 개의 테이블에 같은 칼럼명이 존재하는 경우, DBMS 의 옵티마이저는 어떤 칼럼을 사용해야 할지 모르기 때문에 파싱 단계에서 에러가 발생한다.

 

(2) SQL 에 대한 가독성이나 유지보수성을 높이는 효과이다.

미래에도 두 집합에서 유일하다는 보장은 없기 때문에 향후 발생할 오류를 방지하고 일관성을 위함이다.

 

 

 

 

INNER JOIN 에 참여하는 대상 테이블이 N 개 라면, 

N 개의 테이블로부터 필요한 데이터를 조회하기 위해 필요한 JOIN 조건은 대상 테이블의 개수에서 하나 뺀 N-1 개 이상이 필요하다.

 

 

 

 

 

 


① 선수 - 팀 EQUI JOIN 사례

 

선수 - 팀 테이블 관계도

 

" 선수 테이블의 TEAM_ID 칼럼 " 이 " 팀 테이블의 TEAM_ID " 와 PK (팀) 와 FK (선수) 의 관계에 있다.

 

 

 

 

EQUI JOIN 설명을 위한 데이터 재배열 후

 

 

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, PLAYER.TEAM_ID, TEAM.TEAM_NAME, TEAM_REGION_NAME
FROM PLAYER, TEAM
WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID;

 

 

 

INNER JOIN을 사용하면,

SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, PLAYER.TEAM_ID, TEAM.TEAM_NAME, TEAM_REGION_NAME
FROM PLAYER
INNER JOIN TEAM ON PLAYER.TEAM_ID = TEAM.TEAM_ID;

SELECT 절에서 칼럼에 대한 ALIAS 를 사용하는 듯이

FROM 절의 테이블에 대해서도 ALIAS 를 사용할 수 있다.

테이블명이 길고 SQL 복잡도가 높아지면 가독성이 떨어져서 테이블명 대신 ALIAS 를 주로 사용한다.

 

 

 

ALIAS 를 사용하면,

SELECT PLAYER.PLAYER_NAME 선수명, PLAYER.BACK_NO 백넘버, PLAYER.TEAM_ID 팀코드, TEAM.TEAM_NAME 팀명, TEAM_REGION_NAME 연고지
FROM PLAYER P, TEAM T
WHERE P.TEAM_ID = T.TEAM_ID;

 

 

 

 

 


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

 

WHERE 절에서 JOIN 조건 이외의 검색 조건에 대한 제한 조건을 덧붙여 사용한다.

EQUI JOIN 의 최소한의 연관 관계를 위해서 테이블 개수 -1 개의 JOIN 조건을 WHERE 절에 명시하고,

부수적인 제한 조건을 논리 연산자를 통하여 추가로 입력하는 것이 가능하다.

 

 

 

(예제)

 

(1) WHERE 절에 포지션이 골키퍼( GK )인 선수들에 대한 데이터만을 백넘버 순으로 출력한다.

SELECT PLAYER.PLAYER_NAME 선수명, PLAYER.BACK_NO 백넘버, PLAYER.TEAM_ID 팀코드, TEAM.TEAM_NAME 팀명, TEAM_REGION_NAME 연고지
FROM PLAYER P, TEAM T
WHERE P.TEAM_ID = T.TEAM_ID
      AND P.POSITION = 'GK'
ORDER BY P.BACK_NO;

WHERE 절에 AND 로 다른 조건을 추가하고 ORDER BY 로 백넘버 순으로 출력했다.

 

 

 

 

 

 


③ 팀 - 구장 EQUI JOIN 사례

 

EQUI JOIN 설명을 위한 팀 - 구장 테이블 관계도

 

 

 

 

(예제)

 

(1) TEAM 테이블과 STADIUM 테이블 의 관계를 이용해서

    소속팀이 가지고 있는 STADIUM 정보를 TEAM 정보와 함께 출력한다.

SELECT T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, ...
FROM TEAM T, STADIUM S
WHERE T.STADIUM_ID = S.STADIUM_ID;

 

INNER JOIN 사용,

SELECT T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, ...
FROM TEAM T
INNER JOIN STADIUM ON T.STADIUM_ID = S.STADIUM_ID;

 

 

 

 

 

 

 

 

 

 


3. Non EQUI JOIN

▷ NON EQUI ( 비등가 ) JOIN

    : 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우 사용한다.

     " = " 연산자가 아닌 다른 연산자 ( BETWEEN , > , >= , < , <= 등 ) 를 사용하여 JOIN 을 수행한다.

      데이터 모델에 따라 Non EQUI JOIN 이 불가능한 경우도 있다.

      

 

 

 

* NON EQUI JOIN 형태   ( BETWEEA a AND b 사례 )

SELECT 테이블1.칼럼명, 테이블2.칼럼명, ...
FROM 테이블1, 테이블2
WHERE 테이블1.칼럼명 BETWEEN 테이블2.칼럼명1 AND 테이블2.칼럼명2;

 

 

 

(예제)

 

(1) 어떤 사원이 받고 있는 급여가 어느 등급에 속하는 등급인지 알고 싶은 요구사항

    ( 사원 테이블과 가상의 급여등급 테이블 )

SELECT E.ENAME, E.JOB, S.GRADE FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;

 

 

NON EQUI JOIN 설명을 위한 두 개의 테이블 관계도

 

사원 테이블에서 사원들의 급여가 급여등급 테이블의 등급으로 표시되기 위해서는 " = " 연산자로 JOIN 이용이 안된다.

 

 

 

데이터 재배열 후

사원 테이블의 데이터를 기준으로 급여등급 테이블의 어느 등급에 속하는지 1:1 로 해당하는 값들을 나열해보았다.

 

 

 

 

 

(2) 사원 모두에 대해 급여와 급여 등급을 알아본다.

SELECT E.ENAME 사원명, E.SAL 급여, S.GRADE 급여등급 FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;

 

 

 

 

 

 

 

 

 


4. ' 3개 이상 ' TABLE JOIN

 

세 개의 테이블에 대한 JOIN 은 WHERE 절에 2 개 이상의 JOIN 조건이 필요하다.

 

 

 

(예제)

 

(1) 선수 테이블, 팀 테이블, 운동장 테이블 을 JOIN 한다.

SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지, T.TEAM_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.TEAM_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 선수명;

 

 

 

 

 

 

 

 


JOIN 이 필요한 기본적인 이유는 정규화 이다.

 

정규화란 불필요한 데이터의 정합성을 확보하고 이상현상 발생을 피하기 위해, 테이블을 분할하여 생성하는 것이다.

 

특정 요구조건을 만족하는 데이터들을 분할된 테이블로부터 조회하기 위해서 테이블 간의 논리적인 연관관계가 필요하다.

그런 관계성을 통해서 다양한 데이터들을 출력할 수 있다.

이런 논리적인 관계를 구체적으로 표현하는 것이 SQL 문장의 JOIN 조건이다.

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

댓글