<목차> |
6. 조인 (JOIN)
조인은 여러 테이블을 하나의 테이블로 만드는 과정
JOIN 개요
- 두 개 이상의 테이블들을 연결 또는 결합하여 데이터를 출력하는 것
- 관계형 데이터베이스의 가장 큰 장점이면서 대표적인 핵심 기능
- PK와 FK의 값을 기반으로 JOIN 성립
> 선수라는 테이블과 팀이라는 테이블이 있는 경우, 선수 테이블을 기준으로 필요한 데이터를 검색하고 이 데이터와 연관된 팀 테이블의 특정 행을 찾아오는 과정
> 팀과 운동장 테이블도 조인 조건을 통해 필요한 데이터를 조합해서 가져올 수 있으며, 하나의 SQL 문장에서 선수, 팀, 운동장 등 여러 테이블을 조인해서 사용 가능
- 조인을 잘못하면 데이터 많아짐. (중복된 데이터가 있을 때 JOIN을 신중히 해야 함.)
- 주의할 점은 FROM 절에 여러 테이블이 나열되더라도 SQL에서 데이터를 처리할 때는 단 두 개의 집합 간에만 조인이 발생.
> FROM 절에 A, B, C 테이블이 나열되었더라도 특정 2개의 테이블만 먼저 조인 처리되고, 2개의 테이블이 조인되어서 처리된 새로운 데이터 집합과 남은 한 개의 테이블이 다음 차례로 조인.
JOIN이 필요한 기본적인 이유는 정규화에서부터 출발 - 하나의 테이블의 모든 데이터를 집중시켜 놓고 그 테이블로부터 필요한 데이터를 조회할 수도 있지만, 이럴 경우 가장 중요한 데이터의 정합성에 더 큰 비용을 지불해야 하며, 데이터 추가, 삭제, 수정하는 작업 역시 상당한 노력 요구.
> 테이블을 정규화하여 테이블을 분할함으로써 해결.
> 특정 요구조건을 만족하는 데이터들을 분할된 테이블로부터 조회하기 위해서는 테이블 간에 논리적인 연관관계가 필요하고 그런 관계성을 통해서 다양한 데이터들을 출력 가능.
> JOIN 조건: 이런 논리적인 관계를 구체적으로 표현.
EQUI JOIN (등가 조인)
- 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하는 경우에 사용되는 방법
- PK ↔ FK 의 관계를 기반으로 함.
> 그러나 반드시 PK ↔ FK의 관계로만 EQUI JOIN이 성립하는 것은 아님.
(이 기능은 계층형이나 망형 데이터베이스와 비교해서 관계형 데이터베이스의 큰 장점)
- JOIN의 조건은 WHERE 절에 기술하게 되는데 "=" 연산자를 사용해서 표현
- 참여하는 대상 테이블이 N개라고 했을 때, N개의 테이블로부터 필요한 데이터를 조회하기 위해 필요한 JOIN 조건은 "N-1"
- SELECT 구문에는 단순히 칼럼명이 오지 않고 "테이블명. 칼럼명"처럼 테이블명과 칼럼명 같이 표기.
> JOIN에 사용되는 두 개의 테이블에 같은 칼럼명이 존재하는 경우 DBMS 옵티마이저는 어떤 칼럼을 사용해야 할지 모르기 때문에 파싱 단계에서 에러 발생
> 개발자나 사용자가 조회할 데이터가 어느 테이블에 있는 칼럼을 말하는 것인지 쉽게 알 수 있게 함. (가독성이나 유지보수성 높임)
선수 테이블과 팀 테이블에서 K-리그 소속 선수들의 이름, 백넘버와 그 선수가 소속되어 있는 팀명 및 연고지를 알고 싶다는 요구 사항을 받았을 경우,
선수 테이블의 소속팀 코드(PK)를 기준으로 팀 테이블에 들어 있는 데이터를 아래와 같이 바꿔 줌.
▼
SELECT PLAYER.PLAYER_NAME, PLAYER.BACK_NO, PLAYER.TEAM_ID, TEAM.TEAM_NAME, TEAM.REGION_NAME FROM PLAYER, TEAM (또는 PLAYER INNER JOIN TEAM) WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID; |
JOIN 조건 기술할 때 주의 사항
- 만약 테이블에 대한 ALIAS (AS)를 적용해서 SQL 문장을 작성했을 경우, WHERE 절과 SELECT 저에는 테이블명이 아닌 테이블에 대한 ALIAS를 사용. (하나의 SQL 문장 내에서 유일하게 사용하는 칼럼명이라면 ALIAS를 붙이지 않아도 됨.)
- FROM 절에서 테이블에 대한 ALIAS를 정의했는데, SELECT 절이나 WHERE 절에서 테이블명을 사용한다면 DBMS의 옵티마이저가 칼럼명이 부적합하다는 에러를 파싱 단계에서 발생시킴.
[예제 및 실행결과] SELECT PLAYER.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명 FROM PLAYER P, TEAM T (ALIAS 지정) WHERE P.TEAM_ID = T.TEAM_ID AND P.POSITION = "GK" ORDER BY P.BACK_NO; SELECT PLAYER.PLAYER_NAME 선수명, P.BACK_NO 백넘버, * 1행에 오류: ERROR: 열명이 부적합하다 |
비등가 조인 (NON EQUI JOIN)
- 두 개의 테이블 간에 칼럼 값들이 서로 정확하게 일치하지 않는 경우에 사용.
- "=" 연산자가 아닌 다른 (Between, >, >=, <, <= 등) 연산자들을 사용하여 JOIN 수행
어떤 사원이 받고 있는 급여가 어느 등급에 속하는 등급인지 알고 싶다는 요구사항에 대한 NON EQUI JOIN
SELECT E.NAME, E.JOB, E.SAL, S.GRADE FROM EMP E, SALGRADE S WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL; |
사원들과 사원들의 급여가 급여등급 테이블의 어느 급여등급에 해당되는지 알아보기 위해서 사원 테이블에 들어 있는 데이터를 기준으로 급여등급 테이블의 어느 등급에 속하는지 1:1로 해당하는 값들을 나열
▼
사원 모두에 대한 급여와 급여등급을 알아보는 SQL 문 작성
SELECT E.NAME 사원명, E.SAL 급여, S.GRADE 급여등급 FROM EMP E, SALGRADE S WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL; |
3개 이상 TABLE JOIN
선수들 별로 홈그라운드 경기장이 어디인지를 출력하고 싶다고 했을 때, 선수 테이블과 운동장 테이블이 서로 관계가 없으므로 중간에 팀 테이블이라는 서로 연관관계가 있는 테이블을 추가해서 세 개의 테이블을 JOIN 해야만 원하는 데이터를 얻을 수 있음.
▶ 선수 테이블의 소속팀코드(TEAM_ID)가 팀 테이블의 팀코드(TEAM_ID)와 PK-FK 관계
▶ 운동장 테이블의 운동장코드(STADIUM_ID)와 팀 테이블의 전용구장코드(STADIUM_ID)가 PK-FK 관계
SQL 문
(세 개의 테이블에 대한 JOIN 이므로 WHERE 절에 2개 이상의 JOIN 조건 필요)
SELECT P.PLAYER_NAME 선수명, P.POSITION 포지션, T.REGION_NAME 연고지, T.TEAM_NAME 팀명, S.STADIUM 구장명 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 구장명 FROM PLAYER P INNER JOIN TEAM T, STADIUM S ON P.TEAM_ID = T.TEAM_ID INNER JOIN STADIUM S ON T.STADIUM_ID = S.STADIUM_ID ORDER BY 선수명; |
이전글
다음글
'자격증 > SQLD' 카테고리의 다른 글
SQLD 2과목 SQL 활용 - 서브쿼리 (1) | 2024.01.15 |
---|---|
SQLD 2과목 SQL 기본 및 활용 - 표준 조인 (0) | 2024.01.14 |
SQLD 2과목 SQL 기본 및 활용 - GROUP BY, HAVING 절 (1) | 2024.01.12 |
SQLD 2과목 SQL 기본 및 활용 - WHERE 절 (1) | 2024.01.11 |
SQLD 2과목 SQL 기본 및 활용 - 함수(2) (0) | 2024.01.10 |