CS/DataBase

JOIN

HJ39 2024. 1. 2. 18:19

중복 데이터를 피하기 위해서 데이터를 쪼개 여러 테이블로 나눠서 저장된 관계형 데이터베이스에서 분리된 데이터를 원하는 결과로 도출하기 위해 여러 테이블을 조합하기 위해 컬럼 기준으로 행을 합쳐주는 연산

 

□ JOIN 예시

SELECT ...
FROM R, S
WHERE R.A <비교연산자> S.B;

다음과 같은 SELECT문은 릴레이션 R의 Attribute A와 릴레이션 S의 Attribute B를 비교연산자를 통해 조건을 만족하는 튜플들의 집합을 구한다. 

R.A <비교연산자> S.B; 인 경우 R.A와 S.B는 주로 기본 키와 외래 키의 관계를 갖는다.

 

특징
- N개의 릴레이션을 연관시키기 위해서는 N-1개의 JOIN 조건이 필요하다.
- JOIN 조건을 생략하거나 틀리게 표현한 경우 카티션 곱이 생성된다.
더보기
SELECT * FROM Company.EMPLOYEE;
SELECT * FROM Company.DEPARTMENT;

 

  • 셀프 조인

자기 자신의 테이블을 조인하는 방법

 

질의: 모든 사원에 대해서 사원의 이름과 직속 상사의 이름을 검색하고 월급이 많은 순서로 정렬하여 출력하시오.

SELECT E.EMPNAME as MENTEE, E.SALARY, M.EMPNAME as MENTO
from Company.EMPLOYEE E, Company.EMPLOYEE M
where E.MANAGER = M.EMPNO
order by E.SALARY DESC;

 

 

  • 중첩 질의

외부 질의 안에 중첩된 쿼리문들을 중첩 질의라고 한다.

 

  • 한 개의 스칼라 값이 반환되는 경우
select EMPNAME, TITLE
from Company.EMPLOYEE
where TITLE = (select TITLE from Company.EMPLOYEE where EMPNAME = "박영권");
-- EMPLOYEE 릴레이션에서 EMPNAME이 "박영권"인 사람의 직급과 같은 사람들을 EMPLOYEE 릴레이션에서 조회한다.

 

  • 한 개의 Attribute로 이루어진 릴레이션이 반환된 경우

외부 질의의 WHERE절에서 IN, ANY(SOME), ALL, EXISTS 같은 연산자를 사용한다.

연산자 설명
IN 한 Attribute가 값들의 집합에 속하는지 테스트할 때 사용
ANY 하나 이상의 값들과 어떤 관계를 갖는지 테스트할 때 사용
EXISTS 여러 Attribute로 이루어진 릴레이션이 반환되는 경우에 사용
ALL 한 Attribute가 값들의 집합에 속하는 모든 값들과 어떤 관계를 갖는지 테스트할 때 사용
=, <>, <=, <>, >=, >의 비교연산자도 같이 사용

 

select EMPNAME, TITLE, DNO
from Company.EMPLOYEE
where DNO in (select DEPTNO from Company.DEPARTMENT where DEPTNAME = "영업" OR DEPTNAME = "개발");
-- 영업부나 개발부에 근무하는 사람들의 이름과 직급을 조회한다.

 

 

  • 여러 Attribute들로 이루어진 릴레이션이 반환되는 경우
select EMPNAME
from Company.EMPLOYEE E
where EXISTS
        (select * 
         from Company.DEPARTMENT D 
         where E.DNO = D.DEPTNO 
         	AND (DEPTNAME = "영업" OR DEPTNAME = "개발"));
-- 영업부나 개발부에서 근무하는 사원들의 이름을 조회

 

 

  • 상관 중첩 질의

위 EXISTS를 사용한 예시에서 외부 질의 from에서 명시된 EMPLOYEE릴레이션을 중첩 질의 WHERE에서 사용되므로 상관 중첩 질의가 적용된다.

 

 

  • 내부 조인(INNER JOIN)

기본 테이블과 조인 테이블 모두 데이터가 존재해야 조회된다.

(교집합으로 생각하면 편하다)

-- 중첩 질의
select EMPNAME, TITLE, DNO
from Company.EMPLOYEE
where DNO in (select DEPTNO from Company.DEPARTMENT where DEPTNAME = "영업" OR DEPTNAME = "개발");

-- INNER JOIN
select EMPNAME, TITLE, DNO
from Company.EMPLOYEE as E
inner join Company.DEPARTMENT as D
	on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = "영업" OR D.DEPTNAME = "개발");

두 쿼리문의 결과 값은 같다.

 

 

  • 외부 조인(OUTER JOIN)

내부 조인은 두 테이블에 모두 데이터가 있어야만 결과가 나오지만, 외부 조인은 한쪽에만 데이터가 있어도 결과가 조회된다.

SELECT <열 목록>
FROM <첫 번째 테이블(LEFT 테이블)>
    <LEFT | RIGHT | FULL> OUTER JOIN <두 번째 테이블(RIGHT 테이블)>
     ON <조인 조건>
[WHERE 검색 조건]

 

 

  • LEFT OUTER JOIN

□ 교집합을 포함하는 경우

select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	left outer join Company.DEPARTMENT as D
		on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = "영업" OR D.DEPTNAME = "개발");

 

□ 교집합을 포함하지 않는 경우 (DEPTNAME이 NULL인 경우를 제외)

select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	left outer join Company.DEPARTMENT as D
		on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = "영업" OR D.DEPTNAME = "개발")
where D.DEPTNAME is NOT NULL

 

 

  • RIGHT OUTER JOIN

select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	right outer join Company.DEPARTMENT as D
		on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = "영업" OR D.DEPTNAME = "개발")

 

 

select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	right outer join Company.DEPARTMENT as D
		on (E.DNO = D.DEPTNO) AND (D.DEPTNAME = "영업" OR D.DEPTNAME = "개발")
where E.DNO is NULL

 

 

  • FULL OUTER JOIN

 

MySQL에서는 FULL OUTER JOIN을 지원하지 않는다고 한다.. 머쓱..

LEFT, RIGHT OUTER JOIN의 결과값 모두 출력된다고 생각하면 된다.

 

 

  • 상호 조인 (CROSS JOIN)

한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인시키는 기능

상호 조인 결과의 전체 행 개수는 두 테이블의 각 행의 개수를 곱한 수만큼 생성된다.

카티션 곱이라고 부른다.

 

□ 양식

SELECT *
FROM <첫 번째 테이블>
    CROSS JOIN <두 번째 테이블>

 

select EMPNAME, TITLE, DNO, DEPTNAME
from Company.EMPLOYEE as E
	cross join Company.DEPARTMENT D

 

 

끝!

 

 

# 참고한 자료

'CS > DataBase' 카테고리의 다른 글

Key  (0) 2024.01.01