본문 바로가기

Data Science/SQLD

[SQLD] SQL 기본 1-9. 조인

반응형

1. JOIN 개요

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

 

일반적인 경우 : PK나 FK 값의 연관에 의해 JOIN이 성립

특수한 경우 : 논리적인 값들의 연관을 이용한 JOIN

 

단, FROM 절에 여러 테이블이 나열되더라도 SQL에서 데이터를 처리할 때는 단 두 개의 집합 간에만 조인 발생

 

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

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

 

A, B, C, D 4개의 테이블을 조인 시

: ( ( (A JOIN D) JOIN C) JOIN B) -> A, D -> , C-> ,B [옵티마이저에 의한 조인 순서 결정]

 


2. EQUI JOIN 동등조인, 등가조인

: 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하는 경우 사용 [일반적으로 PK <-> FK 관계 기반]

-> JOIN의 조건은 WHERE 절에 '='을 사용해 표현

 

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

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

테이블명.칼럼명 : 칼럼명이 같은 경우 옵티마이저가 파싱 단계에서 에러 발생하기 때문 / 가독성, 유지보수성 때문

 

FROM 절에 테이블 3개가 표시 -> JOIN 조건은 2개 이상 필요

FROM 절에 테이블 4개가 표시 -> JOIN 조건은 3개 이상 필요

 

JOIN 조건은 WHERE 절에 기술하며, JOIN은 두 개 이상의 테이블에서 필요한 데이터를 출력하기 위한 조건

[FROM절에 조인 조건 명시 / JOIN 조건이 없는 CROSS JOIN]

 

가. 선수-팀 EQUI JOIN

 

(1) 선수 테이블과 팀 테이블에서 K-리그 소속 선수들의 이름, 백넘버와 그 선수 소속되어 있는 팀명 및 연고지 출력

더보기

선수 테이블(PLYAER) 에 있는 소속팀 코드(TEAM_ID) 칼럼이

팀 테이블(TEAM)의 팀코드(TEAM_ID)와 PK(팀 테이블의 팀코드)와 FK(선수 테이블의 소속팀 코드)의 관계

 

SELECT PLAYER.PLAYER_NAME, PLAYER.,BACK_NO, PLAYER.TEAM_ID,

TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER, TEAM

WHERE PLYAER.TEAM_ID = TEAM.TEAM_ID;

 

SELECT PLAYER.PLAYER_NAME, PLAYER.,BACK_NO, PLAYER.TEAM_ID,

TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER INNER JOIN TEAM

ON PLYAER.TEAM_ID = TEAM.TEAM_ID;

-> JOIN 대상 테이블명이 반복해서 등장 -> FROM 절의 테이블에 ALIAS 사용

 

(2) 칼럼과 테이블에 ALIAS 적용해 SQL 수정

더보기

SELECT PLAYER.PLAYER_NAME, PLAYER.,BACK_NO, PLAYER.TEAM_ID,

TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER P, TEAM T

WHERE PLYAER.TEAM_ID = TEAM.TEAM_ID;

 

SELECT PLAYER.PLAYER_NAME, PLAYER.,BACK_NO, PLAYER.TEAM_ID,

TEAM.TEAM_NAME, TEAM.REGION_NAME

FROM PLAYER P INNER JOIN TEAM T

ON PLYAER.TEAM_ID = TEAM.TEAM_ID;

 

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

: WHERE 절에서 JOIN 조건 이외의 검석 조건에 대한 제한 조건 추가

[즉, EQUI JOIN의 JOIN 조건을 WHERE 절에 명시하고, 부수적인 제한 조건을 논리 연산자를 통해 추가로 입력]

 

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

더보기

SELECT P.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명

FROM PLAYER P, TEAM T

WHERE P.TEAM_ID = T.TEAM_ID AND P.POSITION = 'GK';

ORDER BY P.BACK_NO;

 

SELECT P.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명

FROM PLAYER P INNER JOIN TEAM T

ON P.TEAM_ID = T.TEAM_ID

WHERE P.POSITION = 'GK';

ORDER BY P.BACK_NO;

-> 만약 테이블에 대한 ALIAS를 적용해 SQL 문장 작성시,

WHERE 절과 SELECT 절에는 테이블명이 아닌 ALIAS명을 사용

 

(3) FROM 절에 테이블에 대한 ALIAS 정의 후 SELECT절이나 WHERE절에서 테이블명 사용

더보기

SELECT PLAYER.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명

FROM PLAYER P, TEAM T

WHERE P.TEAM_ID = T.TEAM_ID AND P.POSITION ='GK'

ORDER BY P.BACK_NO;

SELECT PLAYER.PLAYER_NAME 선수명, P.BACK_NO 백넘버

 

-> SELECT PLAYER.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명 :열명 부적합

 

다. 팀-구장 EQUI JOIN

(1) 팀 테이블(TEAM)과 구장 테이블(STADIUM)의 관계를 이용해 소속팀이 가지고 있는 전용구장의 정보를 팀의 정보와 함께 출력

더보기

#COLUMN

SELECT TEAM.REGION_NAME, TEAM.TEAM_NAME, TEAM.STADIUM_ID, STADIUM.STADIUM_NAME, STADIUM.SEAT_COUNT

FROM TEAM, STADIUM

WHERE TEAM.STADIUM_ID = STADIUM.STADIUM_ID;

 

SELECT TEAM.REGION_NAME, TEAM.TEAM_NAME, TEAM.STADIUM_ID, STADIUM.STADIUM_NAME, STADIUM.SEAT_COUNT

FROM TEAM INNER JOIN STADIUM

ON TEAM.STADIUM_ID = STADIUM.STADIUM_ID;

 

#ALIAS 

SELECT T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, S.SEAT_COUNT

FROM TEAM T, STADIUM S

WHERE TEAM.STADIUM_ID = STADIUM.STADIUM_ID;

 

SELECT T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, S.SEAT_COUNT

FROM TEAM T INNER JOIN STADIUM S

ON TEAM.STADIUM_ID = STADIUM.STADIUM_ID;

 

#중복되지 않은 칼럼인 경우

SELECT REGION_NAME, TEAM_NAME, T.STADIUM_ID, STADIUM_NAME,

SEAT_COUNT

FROM TEAM T, STADIUM S

WHERE T.STADIUM_ID = S.STADIUM_ID;


3. Non EQUI JOIN 비동등, 비등가 조인

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

 

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

(1) 사원 테이블(EMP)과 가상의 급여등급(SAL_GRADE) 테이블 - 어떤 사원이 받고 있는 급여가 어느 등급에 해당하는지 에 대한 출력

더보기

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

FROM EMP E, SALGRADE S

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

 

(2) 사원 14명 모두에 대해 급여와 급여등급 출력

더보기

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

 

(1) 선수들 별로 홈그라운드 경기장이 어디인지를 출력

[선수 테이블의 소속팀코드(TEAM_ID)가 팀테이블의 팀코드(TEAM_ID)와 PK-FK 관계]

[운동장 테이블의 운동장코드 (STADIUM_ID)와 팀 테이블의 전용구장코드(STADIUM_ID)가 PK-FK 관계]

더보기

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 선수명;

 

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은 정규화에서부터 시작

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

 

#특정 요구조건을 만족하는 데이터들을 분할된 테이블로부터 조회

-> 테이블 간에 논리적인 연관관계가 필요

-> 관계성을 이용한 데이터 출력

-> 관계의 구체적 표현 = JOIN 조건

 

반응형