조인

9mond·2023년 7월 21일
0
post-thumbnail
post-custom-banner

1. 조인(Join)이란

  • 두 개 이상의 테이블을 서로 연결하여 데이터를 검색할 때 사용하는 방법으로 두 개의 테이블을 마치 하나의 테이블인 것처럼 보여주는 것이다.

2. Join의 기본 사용 방법

  • 두 개의 테이블에 하나라도 같은 컬럼이 있어야 한다.,
  • 두 컬럼의 값은 공유 되어야 한다.
  • 보통 조인을 위해 기본키(Primary key)외래키(Foregin key) 를 활용한다.

3. Inner Join

  • 각 테이블에서 조인 조건에 일치되는 데이터만 가져온다
  • 교집합

4. Outer join

  • 조인 조건에 일치하는 데이터일치하지 않은 데이터를 모두 select 한다.
  • 조인 조건에 일치하는 데이터가 없다면 NULL로 가져온다
  • Outer Join은 Inner Join과는 다르게 주 테이블이 어떤 테이블인지가 중요하다.
    그래서 어떤 테이블이 중심이 되느냐에 따라 다시 Left Outer Join, Right Outer Join, Full Outer Join으로 세분화 할 수 있다.
  • 보통은 Left Outer Join을 기본으로 많이 쓴다.
  • Full Outer Join은 속도가 엄청 느려짐.

1-1. Left Outer Join

  • 왼쪽 테이블이 기준이 된다.
  • 조인 조건에 부합하는 데이터가 조인 당하는 테이블(오른쪽)에 있으면 해당 데이터를, 부재하면 NULL로 select 된다.
  • select * from tableA t1 left outer join tableB t2

1-2. Righter Outer Join

  • 오른쪽 테이블이 기준이 된다.
  • 조인 조건에 부합하는 데이터가 조인 당하는 테이블에 있으면 해당 데이터를, 부재하면 NULL로 select가 된다.
  • select * from tableA t1 right outer join tableB b2

1-3. Full Outer Join

  • 양쪽 테이블 모두가 기준이 된다.
  • 조인 조건에 부합하는 데이터가 조인 당하는 테이블에 있으면 해당 테이블을, 부재하면 NULL로 select 된다.

1-4. ANSI Join vs ORACLE Join

  • SQL은 데이터베이스를 관리하기 위해 만들어진 프로그래밍 언어이며, 데이터베이스를 관리해주는 대부분의 Management System DBMS들은 SQL을 사용한다. 물론 DBMS 자체의 특수성 때문에 SQL의 사용법이 조금씩 다르기도 하지만, 큰 틀에서 보면 나름대로의 보편성을 가지고 있다. 왜냐하면 데이터베이스를 관리한다는 본질은 바뀌지 않기 때문이다.
  • 이를 위해 미국 국립 표준 협회(American National Standards Institute, ANSI)에서도 SQL에 대한 보편적인 문법을 제시하고 있는데, 그것이 바로 ANSI Query이다. Join도 마찬가지로 ANSI문법을 사용하는 경우가 대부분이긴 하지만, 편의에 따라 DBMS만의 자체 문법을 사용하기도 한다. 대표적으로 Oracle에서 사용하는 Oracle Join이 있다.

예시

/* inner join */ 
-- 부서를 할당 받은 사람만 조회

SELECT	e.EMPLOYEE_ID , e.FIRST_NAME , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM 	EMPLOYEES e 
	INNER JOIN 	DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
;
-- 빠진 사람 조회
SELECT 	*
FROM 	EMPLOYEES e 
WHERE 	DEPARTMENT_ID IS NULL
;

/* left outer join */
-- EMPLOYEES를 기점으로 다 가져옴
SELECT	e.EMPLOYEE_ID , e.FIRST_NAME , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM 	EMPLOYEES e 
	LEFT OUTER JOIN 	DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
;

/* rihgt outer join */
-- DEPARTMENTS가 기점으로 다 가져옴
SELECT	e.EMPLOYEE_ID , e.FIRST_NAME , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM 	EMPLOYEES e 
	RIGHT OUTER JOIN 	DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
;

/* inner join */
SELECT	e.EMPLOYEE_ID , e.FIRST_NAME , d.DEPARTMENT_ID , d.DEPARTMENT_NAME, l.LOCATION_ID ,l.CITY ,l.STREET_ADDRESS, j.JOB_ID ,j.JOB_TITLE  
FROM 	EMPLOYEES e 
	INNER JOIN 	DEPARTMENTS d 
	ON 	e.DEPARTMENT_ID = d.DEPARTMENT_ID 
	INNER JOIN 	LOCATIONS l 
	ON 	d.LOCATION_ID = l.LOCATION_ID
	INNER JOIN 	JOBS j 
	ON	e.JOB_ID =j.JOB_ID 
WHERE 	l.CITY ='Seattle'
;


/* full outer join */
-- 두 개의 테이블에 있는 모든 정보를 가져옴
SELECT	e.EMPLOYEE_ID , e.FIRST_NAME , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM 	EMPLOYEES e 
	FULL OUTER JOIN DEPARTMENTS d 
	ON	e.DEPARTMENT_ID = d.DEPARTMENT_ID 
;

-- left outer join, inner join
-- 문제1) 사원들의 이름, 부서번호, 부서명을 출력하라
-- 106건
SELECT e.FIRST_NAME , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM EMPLOYEES e 
	INNER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
;

-- 107건
SELECT e.FIRST_NAME , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM EMPLOYEES e 
	LEFT outer JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
;


-- 문제2) 30번 부서의 사원들의 이름,직업,부서명을 출력하라
SELECT e.FIRST_NAME , j.JOB_TITLE, d.DEPARTMENT_NAME , e.JOB_ID 
FROM EMPLOYEES e 
	INNER JOIN JOBS j 
	ON e.JOB_ID  = j.JOB_ID
	INNER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID =d.DEPARTMENT_ID 
	WHERE e.DEPARTMENT_ID = '30'
;

-- 문제3) 커미션을 받는 사원의 이름, 직업, 부서번호,부서명을 출력하라
SELECT e.FIRST_NAME , j.JOB_TITLE ,e.JOB_ID , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM EMPLOYEES e 
	INNER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
	INNER JOIN JOBS j 
	ON e.JOB_ID = j.JOB_ID 
WHERE e.COMMISSION_PCT IS NOT NULL 
;


-- 문제4) 지역번호 2500 에서 근무하는 사원의 이름, 직업,부서번호,부서명을 출력하라
SELECT e.FIRST_NAME  ,e.JOB_ID , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM EMPLOYEES e 
	INNER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID  = d.DEPARTMENT_ID 
WHERE d.LOCATION_ID  = 2500
;


-- 문제5) 이름에 A가 들어가는 사원들의 이름과 부서이름을 출력하라
SELECT e.FIRST_NAME , e.JOB_ID , d.DEPARTMENT_NAME , d.DEPARTMENT_ID 
FROM EMPLOYEES e 
	INNER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
WHERE e.FIRST_NAME like '%A%'
;



-- 문제6) 사원이름과 그 사원의 관리자 이름을 출력하라
-- 매니저도 우리 회사 직원이기 때문에
SELECT 	e.FIRST_NAME "사원명" ,e.EMPLOYEE_ID , e.MANAGER_ID ,
		e2.FIRST_NAME "매니저명", e2.EMPLOYEE_ID , e2.MANAGER_ID 
FROM EMPLOYEES e 
	inner JOIN EMPLOYEES e2  
	ON e.MANAGER_ID = e2.EMPLOYEE_ID 
;


-- 문제7) 사원이름과 부서명과 월급을 출력하는데 월급이 3000 이상인 사원을 출력하라
SELECT e.FIRST_NAME ,d.DEPARTMENT_NAME ,e.SALARY 
FROM EMPLOYEES e 
	LEFT OUTER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
WHERE e.SALARY >= 3000

-- 문제8) 급여가 3000에서 5000사이인 사원의 이름과 소속부서명 출력하라
SELECT e.FIRST_NAME , d.DEPARTMENT_NAME , e.SALARY 
FROM EMPLOYEES e 
	LEFT OUTER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
WHERE e.SALARY BETWEEN 3000 AND 5000
;


-- 문제9) 급여가 3000이하인 사원의 이름과 급여, 근무지를 출력하라
SELECT e.FIRST_NAME , e.SALARY , l.CITY 
FROM EMPLOYEES e 
	LEFT OUTER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID
	LEFT OUTER JOIN LOCATIONS l 
	ON d.LOCATION_ID = l.LOCATION_ID 
WHERE SALARY <= 3000


-- 문제10) Steven King의 부서명을 출력하라.
SELECT e.FIRST_NAME ,d.DEPARTMENT_NAME ,  d.DEPARTMENT_ID 
FROM EMPLOYEES e 
	LEFT OUTER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
WHERE e.FIRST_NAME = 'Steven'
AND e.laST_NAME = 'King'
;


-- 문제11) IT부서에서 근무하고 있는 사람들을 출력하라.
SELECT e.FIRST_NAME , e.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM EMPLOYEES e 
	LEFT OUTER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
WHERE d.DEPARTMENT_NAME = 'IT'
;


-- 문제12) EMPLOYEES 테이블에서 사원번호,이름,업무, EMPLOYEES 테이블의 부서번호, 
-- DEPARTMENTS 테이블의 부서번호,부서명,근무지를 출력하여라.
SELECT e.EMPLOYEE_ID , e.FIRST_NAME ,e.JOB_ID , e.DEPARTMENT_ID , d.DEPARTMENT_ID , d.DEPARTMENT_NAME 
FROM EMPLOYEES e 
	LEFT OUTER JOIN DEPARTMENTS d 
	ON e.DEPARTMENT_ID = d.DEPARTMENT_ID 
;
profile
개발자
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 7월 21일

조인에 대해 상세하게 설명해주셔서 감사합니다. 특히 Outer join과 Inner join의 차이를 이해하는데 큰 도움이 되었습니다. 계속해서 유익한 정보 공유 부탁드립니다!

답글 달기