코딩 기록들

[Database Programming] 6.조인(JOIN)에 대하여 (+INNER JOIN) 본문

카테고리 없음

[Database Programming] 6.조인(JOIN)에 대하여 (+INNER JOIN)

코딩펭귄 2024. 2. 19. 17:25

조인 JOIN

집합연산자 vs 조인 

- 집합연산자를 사용한 결과는 : 2개이상 SELECT문의 결과값을 '세로'로 연결한 것

- 조인을 사용한 결과 : 2개이상 테이블 데이터를 '가로'로 연결한것

테이블 별칭 설정

- FROM절에 지정한 테이블에는 SELECT절의 열에 사용한것처럼 별칭 지정할 수 있다 -> 명시한 테이블 이름에서 한 칸 띄운 후 지정함

FROM 테이블이름1 별칭1, 테이블이름2 별칭2 ..
JOIN관계에 있는 데이터에 따라 여러가지 형태의 관계가 형성됨

1) 1 : 1 ( 만들어서는 안되는 관계 )

- 한 테이블의 PK가 다른 테이블의 FK에 하나만 존재하는 관계 

- , 컬럼의 수가 40개 이상 넘어갈 경우엔 테이블을 분리하여 1 : 1 관계를 맺어야 함

2) 1 : N  

- 한 테이블의 PK가 다른 테이블의 FK에 여러 개가 존재하는 관계

- 가장 흔하게 만들게 되는 관계

ex) 한 명의 회원(PK)이 여러 개의 상품을 주문(FK)한다 (=fk가 중복되는 형태)

      한 명의 회원(PK)이 여러 개의 게시글을 작성 (FK) 한다.

3) N : N (물리적으로 존재할 수 없는 관계)

- N : N 관계는 별도의 테이블을 만들어 1 : N 으로 해소해야 함


 

조인의 종류

- 대상데이터를 어떻게 연결하느냐에 따라 내부조인(등가조인, 비등가조인, 자체조인 ) / 외부조인으로 구분함

(등가, 자체 조인은 조인조건에 해당하는 데이터가 존재할경우에만 출력하기때문에 내부조인이라고 부름)

1. 등가조인
=내부조인 INNER JOIN = 단순조인 SIMPLE JOIN

- 테이블을 연결한 후 출력행을 각 테이블의 특정열에 일치한 데이터를 기준으로 선정하는 방식

- 일반적으로 가장 많이 사용되는 조인방식

- 테이블간 PK – FK 로 연결해 관련정보들을 가져옴 ex) 하나의 부서(PK)에 여러 명의 사원(FK)이 근무중

- 테이블 2개를 하나로 합치는것

- INNER 조인 = 교집합 이라고 생각하기!(같은부분만 가져옴)

 

2. 비등가조인

- 등가조인 방식 외의 방식을 의미함

- 조인 조건이 특정 열의 일치여부를 검사하는 방식 외에 다른 방식도 사용할수있음을 기억할것

 

3. 자체조인

- 하나의 테이블을 여러개의 테이블처럼 활용하여 조인하는 방식 -> 물리적으로 동일한 테이블 여러개를 사용할때 발생할수있는 문제점을 해결함

- FROM절에 같은테이블을 여러번 명시하되, 테이블의 별칭만 다르게 지정하는 방식으로 사용

 

4. 외부조인 (OUTER JOIN)

- 두 테이블 간 조인 수행해서 조인 기준 열의 한 쪽이 NULL이어도 강제로 출력하는 방식

 


INNER JOIN

•A TABLE의  PK값과 B TABLE의 FK 값이 같은 ROW만 조회됨 (교집합부분만 조회됨)

 
SELECT [COLUMN], [COLUMN], […]
FROM [TABLE A] A
INNER JOIN [TABLE B] B
ON A.PK = B.FK

WHERE [CONDITIONS]

           ↓

SELECT A.*, B.*
FROM STUDENT A
INNER JOIN TEACHER B
ON B.TEACHER_ID = A.TEACHER_ID

 

 

 

sub query vs inner join?

- sub query 를 쓰는 목적 : 여러 테이블을 연결해서 한 테이블의 정보만 조회 할 때 사용

- inner join을 쓰는 목적 : 여러 테이블을 연결해서 여러 테이블의 정보를 동시에 조회할 때 사용

 

INNER JOIN 문법
SELECT A.*
	  ,B.*
  FROM TABLE A
 INNER JOIN TABLE B
    ON A.PK = B.FK
;
-- 단, PK와 FK의 순서(위치)는 바껴도 상관없음

- 표준SQL인 ANSI SQL에서는 INNER JOIN이라는 표현을 INNER 생략하고 'JOIN'으로만도 표현가능

- PK와 FK의 순서(위치)는 바껴도 상관없음

INNER JOIN 예제
-- EMPLOYEES와 DEPARTMENTS의 모든 정보를 조회
-- 부서에서 근무중인 사원들의 사원정보와 부서정보를 모두조회
SELECT E.*
     , D.*
  FROM EMPLOYEES E
 INNER JOIN DEPARTMENTS D
    ON D.DEPARTMENT_ID = E.DEPARTMENT_ID 
;
 
-- 사원들이 근무하는 부서의 이름과 지역의 도시명, 사원들의 이름을 조회한다
 SELECT D.DEPARTMENT_NAME 
 	  , E.FIRST_NAME
 	  , L.CITY 
   FROM EMPLOYEES E
  INNER JOIN DEPARTMENTS D
  	 ON D.DEPARTMENT_ID = E.DEPARTMENT_ID
  INNER JOIN LOCATIONS L
     ON L.LOCATION_ID = D.LOCATION_ID 
;
-- 사원번호가 150번 이하인 사람들의 이름과 성, 연봉, 직무아이디, 직무명을 조회
SELECT E.FIRST_NAME 
     , E.LAST_NAME 
     , E.SALARY 
     --E.JOB_ID -FK
     , J.JOB_ID --PK 를 가져오는것이 유리함
     , J.JOB_TITLE 
  FROM EMPLOYEES E
  JOIN  JOBS J
    ON J.JOB_ID = E.JOB_ID 
 WHERE E.EMPLOYEE_ID <= 150
;

 

-- 부서번호, 부서명, 부서장의 사원번호, 부서장의 이름, 부서장의 성, 부서장의 직무명을 조회한다
SELECT D.DEPARTMENT_ID 
	 , D.DEPARTMENT_NAME 
	 , D.MANAGER_ID 
	 , E.FIRST_NAME
	 , E.LAST_NAME 
	 , J.JOB_TITLE 
  FROM DEPARTMENTS D
  JOIN EMPLOYEES E
    ON E.EMPLOYEE_ID = D.MANAGER_ID  
  JOIN JOBS J
    ON J.JOB_ID = E.JOB_ID 
  ;

 

 

 

-> 120번 부서부터는 MANAGER_ID가 NULL값인걸

   확인할수있다! (JOIN은 교집합연산이기 때문)

 

 

 

 

 

 

 

 

 

 

 

직무가 변경된 적이 있는 사원의 과거 직무명과 현재 직무명을 조회
- 현재직무명 : EMPLOYEES의 직무아이디와 JOBS연결해서 JOBTITLE 가져오면 알수잇음
- 과거직무명 : EMPLOYEES - JOB_HISTORY 연결
SELECT PAST_J.JOB_TITLE 
     , JH.START_DATE 
     , JH.END_DATE
     , NOW_J.JOB_TITLE
     , E.EMPLOYEE_ID 
  FROM EMPLOYEES E
  JOIN JOBS NOW_J --현재직무의 정보
    ON NOW_J.JOB_ID = E.JOB_ID
  JOIN JOB_HISTORY JH
    ON E.EMPLOYEE_ID = JH.EMPLOYEE_ID 
  JOIN JOBS PAST_J -- 과거직무의 정보
    ON PAST_J.JOB_ID = JH.JOB_ID
    
--EMPLOYEES에 있는것 : 현재정보
--JOB HISTORY에 있는것 : 과거정보
 자기가 자기를 참조하는 쿼리
- 메뉴를 출력할때, 계단식 정보를 관리할 떄 많이 사용
- 183번 사원의 이름과 상사정보를 조회한다
SELECT E.FIRST_NAME
     , M.*
  FROM EMPLOYEES E --사원정보
 INNER JOIN EMPLOYEES M -- 상사정보
    ON E.MANAGER_ID = M.EMPLOYEE_ID
 WHERE E.EMPLOYEE_ID = 183
;

 

SELECT col -> col  대신 쓰는 쿼리 : 스칼라scala 쿼리 -> 사용x (성능저하)

   FROM table -> table 대신 쓰는 쿼리 : INLINE VIEW

WHERE col 연산자 값 -> 값 대신에 쓰는 쿼리 = 서브쿼리

 

 

(성능이 떨어지기 때문에 사용지양할것)

order by,

group by 

scala query