[SQLD] JOIN

Shy·2024년 5월 20일

SQLD

목록 보기
16/23

JOIN 개요

JOIN은 두 개 이상의 테이블을 연결하거나 결합하여 데이터를 조회하는 SQL 연산이다. 이는 관계형 데이터베이스의 핵심 기능 중 하나로, 다양한 조건을 만족하는 복잡한 쿼리를 작성할 때 필수적이다. JOIN은 보통 PRIMARY KEY(PK)FOREIGN KEY(FK)의 관계에 의해 이루어지지만, PK와 FK 관계가 없어도 논리적인 값들의 연관만으로 JOIN이 성립될 수 있다.

  • JOIN의 중요성
    • JOIN은 관계형 데이터베이스의 가장 큰 장점이자 핵심 기능이다.
    • 많은 SQL 문장이 JOIN을 포함하고 있으며, 이는 실생활에서 발생하는 다양한 조건을 만족하는 쿼리를 작성할 때 필요하다.
  • JOIN의 성립 조건
    • 일반적으로 PRIMARY KEY(PK)와 FOREIGN KEY(FK)의 연관에 의해 성립된다.
    • 논리적인 값들의 연관만으로도 성립될 수 있다.
  • JOIN의 동작 방식
    • SQL에서 두 개 이상의 테이블을 JOIN할 때는 항상 두 테이블 간에만 JOIN이 일어난다.
    • 여러 테이블을 JOIN할 때, 특정 두 테이블이 먼저 JOIN된 후 그 결과와 다음 테이블이 JOIN되는 순차적인 처리가 이루어진다.
    • 옵티마이저가 JOIN 순서를 결정한다.

예시

선수 테이블과 팀 테이블이 있을 때, 선수 테이블의 데이터를 검색하고 관련된 팀 테이블의 데이터를 JOIN하여 검색할 수 있다. 이 과정은 선수, 팀, 운동장 등 여러 테이블을 조인하여 데이터를 조합할 수 있다.

  • JOIN의 순서
    • 테이블 A, B, C, DJOIN할 경우, 옵티마이저는 ( ( (A JOIN D) JOIN C) JOIN B)와 같이 순차적으로 JOIN을 처리한다.
    • 테이블의 JOIN 순서는 옵티마이저가 결정하며, 이는 주요 튜닝 포인트가 된다.

EQUI JOIN

EQUI JOIN은 두 테이블 간의 칼럼 값들이 정확히 일치하는 경우에 사용하는 JOIN 방법이다. 대부분 PK와 FK 관계를 기반으로 하지만, 반드시 이 관계만을 사용하는 것은 아니다.

EQUI JOIN의 특징은 다음과 같다.

  • WHERE 절이나 ON 절을 사용하여 두 테이블 간의 칼럼 값이 일치하는 조건을 기술한다.
  • “=” 연산자를 사용하여 JOIN 조건을 표현한다.

예시

-- WHERE 절을 사용한 EQUI JOIN
SELECT PLAYER.PLAYER_NAME 선수명, TEAM.TEAM_NAME 소속팀명 
FROM PLAYER, TEAM 
WHERE PLAYER.TEAM_ID = TEAM.TEAM_ID;
-- INNER JOIN을 명시하여 사용하는 EQUI JOIN
SELECT PLAYER.PLAYER_NAME 선수명, TEAM.TEAM_NAME 소속팀명 
FROM PLAYER INNER JOIN TEAM 
ON PLAYER.TEAM_ID = TEAM.TEAM_ID;
  • 칼럼 명시
    • 테이블명.칼럼명 형식으로 특정 칼럼에 접근하여 어떤 테이블에 속한 칼럼인지 명시한다.
    • 이는 동일한 칼럼명이 존재할 경우 발생하는 혼동을 방지하고 SQL의 가독성과 유지보수성을 높이는 데 도움이 된다.

INNER JOIN의 조건

  • INNER JOIN에 참여하는 테이블이 N개일 때, 필요한 JOIN 조건은 N-1개 이상이다.
  • 예를 들어, FROM 절에 3개의 테이블이 표시되어 있다면 JOIN 조건은 2개 이상 필요하다.

JOIN은 관계형 데이터베이스의 필수적인 기능으로, 다양한 테이블 간의 데이터를 결합하여 원하는 정보를 조회할 수 있게 한다. EQUI JOIN은 이러한 JOIN 중에서도 가장 기본적인 형태로, 두 테이블 간의 칼럼 값이 정확히 일치하는 조건을 사용한다. 이를 통해 복잡한 쿼리를 쉽게 작성하고, 다양한 데이터를 조합하여 출력할 수 있다.

1️⃣ 선수-팀 EQUI JOIN 사례

EQUI JOIN을 이용하여 선수(PLAYER) 테이블과 팀(TEAM) 테이블에서 K-리그 소속 선수들의 이름, 백넘버, 소속된 팀명, 연고지를 조회하는 사례를 설명한다.

  • 선수(PLAYER) 테이블과 팀(TEAM) 테이블의 관계는 다음과 같다.
    • PLAYER 테이블: 선수의 이름, 백넘버, 소속팀코드(TEAM_ID) 등이 저장된다.
    • TEAM 테이블: 팀의 이름, 팀코드(TEAM_ID), 연고지(REGION_NAME) 등이 저장된다.
    • PK-FK 관계: PLAYER 테이블의 TEAM_ID가 TEAM 테이블의 TEAM_ID와 연결된다.

1. SQL 쿼리 작성

-- 기본 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을 명시한 EQUI 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;
선수명백넘버팀코드팀명연고지
이고르21K06아이파크부산
오비나26K10시티즌대전
윤원일45K02삼성블루윙즈수원
페르난도44K04유나이티드인천
레오45K03스틸러스포항
실바45K07드래곤즈전남
무스타파77K04유나이티드인천
에디7K01 울산현대울산
알리송14K01울산현대울산
쟈스민33K08일화천마성남
디디8K06아이파크부산

ALIAS 사용

테이블명이 길고 SQL의 복잡도가 높아지면 가독성을 높이기 위해 ALIAS를 사용할 수 있다.

-- ALIAS를 사용한 EQUI JOIN
SELECT 
    P.PLAYER_NAME 선수명, 
    P.BACK_NO 백넘버, 
    P.TEAM_ID 팀코드, 
    T.TEAM_NAME 팀명, 
    T.REGION_NAME 연고지 
FROM 
    PLAYER P, TEAM T 
WHERE 
    P.TEAM_ID = T.TEAM_ID;
-- INNER JOIN을 명시한 ALIAS 사용
SELECT 
    P.PLAYER_NAME 선수명, 
    P.BACK_NO 백넘버, 
    P.TEAM_ID 팀코드, 
    T.TEAM_NAME 팀명, 
    T.REGION_NAME 연고지 
FROM 
    PLAYER P INNER JOIN TEAM T 
    ON P.TEAM_ID = T.TEAM_ID;

ALIAS를 사용해도 결과는 위와 동일하다.

2️⃣ 선수-팀 WHERE 절 검색 조건 사례

EQUI JOIN 조건 외에 WHERE 절을 사용하여 추가적인 검색 조건을 적용하는 방법에 대해 설명한다. 예를 들어, 특정 포지션의 선수들만 조회하거나, 특정 조건에 따라 데이터를 필터링할 수 있다.

  • 기본 EQUI JOIN
    • 먼저, 선수와 팀 테이블을 EQUI JOIN하여 기본적인 데이터를 조회한다.
-- 기본 EQUI JOIN SQL
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;

1. WHERE 절에 추가 조건 적용

위의 기본 EQUI JOIN에 추가 조건을 WHERE 절에 넣어 특정 조건의 데이터를 필터링할 수 있다. 예를 들어, 포지션이 골키퍼('GK')인 선수들만 조회하고, 백넘버 순으로 정렬하는 경우를 살펴보자.

-- WHERE 절에 추가 조건을 포함한 SQL
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;
-- INNER JOIN을 사용한 SQL
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;

실행 결과는 다음과 같다.

선수명백넘버연고지팀명
최종문1전남드래곤즈
정병지1포항스틸러스
박유석1부산아이파크
김승준1대전시티즌
이현1인천유나이티드
김운재1수원삼성블루윙즈
정해운1성남일화천마
권정혁1울산울산현대
최동석1서울FC서울
김창민1전북현대모터스
............

ALIAS 사용 시 주의사항

SQL 문장에서 테이블에 대한 ALIAS를 정의했을 경우, SELECT 절과 WHERE 절에서 테이블명이 아닌 ALIAS를 사용해야 한다. 그렇지 않으면 DBMS가 에러를 발생시킬 수 있다.

-- 잘못된 예제(오류 발생)
SELECT PLAYER.PLAYER_NAME 선수명, P.BACK_NO 백넘버, T.REGION_NAME 연고지, T.TEAM_NAME 팀명
FROM PLAYER P, TEAM T
WHERE P.TEAM_ID = TEAM.TEAM_ID AND P.POSITION = 'GK'
ORDER BY P.BACK_NO;

이 경우, TEAM.TEAM_ID 대신 T.TEAM_ID를 사용해야 한다.

2.팀-구장 EQUI JOIN 사례

팀(TEAM) 테이블과 구장(STADIUM) 테이블을 EQUI JOIN하여 각 팀의 전용 구장 정보를 출력한다.

-- 기본 EQUI JOIN SQL
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;
-- INNER JOIN을 사용한 SQL
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를 사용한 SQL
SELECT T.REGION_NAME, T.TEAM_NAME, T.STADIUM_ID, S.STADIUM_NAME, S.SEAT_COUNT
FROM TEAM T, STADIUM S
WHERE T.STADIUM_ID = S.STADIUM_ID;

실행 결과는 다음과 같다.

REGION_NAMETEAM_NAMESTADIUM_IDSTADIUM_NAMESEAT_COUNT
전북현대모터스D03전주월드컵경기장28000
성남일화천마B02성남종합운동장27000
포항스틸러스C06포항스틸야드25000
전남드래곤즈D01광양전용경기장20009
서울FC서울B05서울월드컵경기장66806
인천유나이티드B01인천월드컵경기장35000
...............

3️⃣ Non EQUI JOIN

Non EQUI(비등가) JOIN은 두 개의 테이블 간의 칼럼 값들이 정확하게 일치하지 않는 경우에 사용되는 JOIN 방식이다. EQUI JOIN= 연산자를 사용하는 반면, Non EQUI JOINBETWEEN, >, >=, <, <= 등의 연산자를 사용하여 JOIN을 수행한다.

1. Non EQUI JOIN의 사용

  • 비등가 조건: Non EQUI JOIN은 칼럼 값들이 정확하게 일치하지 않는 경우에 사용하다.
  • 연산자: BETWEEN, >, >=, <, <= 등의 연산자를 사용한다.

2. Non EQUI JOIN의 예시

사원(EMP) 테이블과 급여등급(SAL_GRADE) 테이블을 사용하여 사원들의 급여가 어느 등급에 속하는지를 조회하는 예시이다.

EMP 테이블

ENAMEJOBSAL
SMITHClerk800
JAMESClerk950
ADAMSClerk1100
WARDSales1250
MARTINSales1250
MILLERClerk1300
TURNERSales1500
ALLENSales1600
CLARKManager2450
BLAKEManager2850
JONESManager2975
SCOTTAnalyst3000
FORDAnalyst3000
KINGPresident5000

SALGRADE 테이블

GRADELOSALHISAL
17001200
212011400
314012000
420013000
530019999
-- Non EQUI JOIN SQL
SELECT E.ENAME 사원명, E.SAL 급여, S.GRADE 급여등급
FROM EMP E, SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL;

실행 결과

사원명급여급여등급
SMITH8001
JAMES9501
ADAMS11001
WARD12502
MARTIN12502
MILLER13002
TURNER15003
ALLEN16003
CLARK24504
BLAKE28504
JONES29754
SCOTT30004
FORD30004
KING50005

3. 기타 비등가 조건

BETWEEN 외에도 “>”나 “<”와 같은 연산자를 사용하면 Non EQUI JOIN에 해당한다.

3개 이상 TABLE JOIN

세 개 이상의 테이블을 JOIN하는 경우를 설명한다. 예를 들어, 선수(PLAYER), 팀(TEAM), 운동장(STADIUM) 테이블을 사용하여 선수별 홈그라운드 경기장을 조회할 수 있다.

1️⃣ 테이블 관계

  • PLAYER 테이블의 소속팀코드(TEAM_ID)는 TEAM 테이블의 팀코드(TEAM_ID)와 연관(PK-FK 관계).
  • TEAM 테이블의 전용구장코드(STADIUM_ID)는 STADIUM 테이블의 운동장코드(STADIUM_ID)와 연관(PK-FK 관계).
-- 기본 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 선수명;

실행 결과는 다음과 같다.

선수명포지션연고지팀명구장명
가비MF수원삼성블루윙즈수원월드컵경기장
가이모토DF성남일화천마성남종합운동장
강대희MF수원삼성블루윙즈수원월드컵경기장
강성일GK대전시티즌대전월드컵경기장
강용DF포항스틸러스포항스틸야드
강정훈MF대전시티즌대전월드컵경기장
...............

2️⃣ JOIN의 중요성

  • 정규화: 데이터베이스의 정규화로 인해 테이블이 분할되고, 이를 다시 결합하여 필요한 데이터를 조회하기 위해 JOIN이 필요하다.
  • SQL 튜닝: JOIN을 잘못 사용하면 시스템 자원 부족이나 응답 시간 지연이 발생할 수 있으므로, JOIN 조건을 신중하게 작성해야 한다.

JOIN을 사용하여 여러 테이블 간의 논리적 연관성을 통해 다양한 데이터를 조합하고 조회할 수 있다. Non EQUI JOIN과 여러 테이블 JOIN은 이를 확장하여 복잡한 쿼리를 작성할 수 있게 해준다.

profile
신입사원...

0개의 댓글