Coding Note/SQL

SQL JOIN 알아보기 (inner join / full outer join / cross join / outer join / self join)

푸린이 2021. 12. 27. 01:26

* Join

- 두 개 이상의 테이블을 연결해서 데이터를 검색하는 방법

- 우리 테이블에 없는 정보를 상대방 테이블에서 꺼내오는 과정

- 보통 두 개 이상의 행(row)들의 공통된 값의 기본키, 외래키를 사용해서 Join

- 연결고리가 있어야 함(부서번호, 지역번호)
- 기본 키(Primary key) : 테이블에서 중복이 되지 않는 키
- 외래 키(Foreign key) : 다른 테이블에서 PK(기본키), UK(유니크키)인 경우가 많다.

- ansi SQL(표준) 문법과 oracle문법 2가지로 작성할 수 있다.

JOIN 종류 중요도
inner join ☆☆☆☆☆
full outer join
cross join  
outer join
  - left out join
  - right out join
☆☆☆
self join ☆☆☆☆☆

 

-- inner Join

-- ansi SQL (표준) : INNER JOIN ~ ON

SELECT e.employee_id, e.first_name,         -- 기본키의 테이블 alias는 생략 가능(e., d.)
    e.department_id, d.department_id,       -- 양쪽 테이블에 있는 컬럼 alias를 생략하면 오류
    d.department_name
FROM employees e INNER JOIN departments d     -- 테이블의 alias 지정
    on e.department_id = d.department_id;

-- oracle

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id

 

-- cross Join

- 하나씩 다 Join 시킴

-- ansi

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e CROSS JOIN departments d;

-- oracle

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e, departments d;

 

-- full outer join

-- ansi

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e FULL OUTER JOIN departments d
    on e.department_id = d.department_id;

-- oracle

- 원래는 없지만, 아래처럼 표현 가능 : left outer join + right outer join

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id(+)
UNION
SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e, departments d
WHERE e.department_id(+) = d.department_id;

- UNION(집합) 위의 쿼리와 아래의 쿼리를 합쳐라

- null 부분까지 모두 출력

 

-- outer join

-- left

--ansi

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e LEFT OUTER JOIN departments d
        ON e.department_id = d.department_id;

- employees 바깥에 있는 부분도 출력 (중심 테이블이 왼쪽)

-- oracle

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id(+);     -- 왼쪽이 중심

 

-- left outer join + 차집합

- 먼저 left outer join 한 다음에 null인 경우만 뽑아라

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id(+)
    AND e.department_id IS NULL;

 

-- right

--ansi

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e RIGHT OUTER JOIN departments d	-- departments 바깥에 있는 부분도 출력
ON e.department_id = d.department_id;

-- oracle

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e, departments d
WHERE e.department_id(+) = d.department_id;     -- 오른쪽이 중심

 

-- right outer join + 차집합

- 먼저 right outer join 한 다음에 null인 경우만 뽑아라

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e, departments d
WHERE e.department_id(+) = d.department_id
    AND e.department_id IS NULL;

 

-- 완전 차집합

-- ansi

SELECT e.employee_id, e.first_name,
    e.department_id, d.department_id,
    d.department_name
FROM employees e FULL OUTER JOIN departments d
    on e.department_id = d.department_id
WHERE e.department_id IS NULL           -- e, d 둘다 null
    OR d.department_id IS NULL;         -- e만 null -> or로 묶어주기

 

-- self join

- 동일한 테이블을 join

SELECT a.employee_id, a.first_name,     -- 같은 테이블이기 때문에 alias 무조건 붙이기
    a.manager_id, b.employee_id,
    b.first_name
FROM employees a, employees b            -- a : 사원 / b : 상사(매니저)        다른 테이블로 생각하기
WHERE a.manager_id = b.employee_id;      -- 사원의 상사 = 상사의 정보  (두가지 다 사원번호임)

-- 조건 추가해보기

SELECT a.employee_id, a.first_name,
    a.manager_id, b.employee_id,
    b.first_name
FROM employees a, employees b
WHERE a.manager_id = b.employee_id
    AND a.employee_id = 168;