[DBMS] 조인(JOIN) 연산
[조인연산]
두 테이블을 결합하는 연산. 서로 다른 테이블에서 데이터를 가져올 때 사용
*MySQL은 OUTER JOIN 지원하지 않아 UNION으로 공부예정

INNER JOIN(교집합) : 조인하는 테이블의 조건이 일치하는(겹치는) 결과만 출력
select * from 테이블명1 inner join 테이블명2 on 테이블명1.속성명 = 테이블명2.속성명;
select * from 테이블명1, 테이블명2 where 테이블명1.속성명 = 테이블명2.속성명;
테이블이 3개인 경우
select * from 테이블명1 , 테이블명2 , 테이블명3
inner join 테이블명2 on 테이블명1.속성명 = 테이블명2.속성명
inner join 테이블명3 on 테이블명1.속성명 = 테이블명3.속성명;


select * from emp inner join dept on emp.deptid=dept.id;

select emp.id, emp.regDate, emp.name, dept.deptName from emp inner join dept on emp.deptid=dept.id;
또는
select emp.id, emp.regDate, emp.name, dept.deptName from emp, dept whrere emp.deptid=dept.id;

select emp.id as '사원번호', emp.regDate as '등록일자', emp.name as '이름', dept.deptName as '부서'
from emp inner join dept on emp.deptid=dept.id;
또는
select emp.id as '사원번호', emp.regDate as '등록일자', emp.name as '이름', dept.deptName as '부서'
from emp, dept where emp.deptid=dept.id;




LEFT JOIN : 왼쪽테이블을 기준으로 조인
select * from 테이블명1 left join 테이블명2 on 테이블명1.속성명 = 테이블명2.속성명;
select * from emp left join dept on emp.deptid=dept.id;

ANTI LEFT JOIN(차집합) : 왼쪽테이블에는 속하지만 오른쪽테이블에는 속하지 않는 차집합
select * from 테이블명1 left join 테이블명2 on 테이블명1.속성명 = 테이블명2.속성명 where 테이블명2.속성명 is null;
select * from emp left join dept on emp.deptid=dept.id where dept.id is null;



RIGHT JOIN : 오른쪽테이블을 기준으로 조인
select * from 테이블명1 right join 테이블명2 on 테이블명1.속성명 = 테이블명2.속성명;
select * from dept right join emp on dept.id=emp.deptid;

ANTI RIGHT JOIN(차집합) : 오른쪽테이블에는 속하지만 왼쪽테이블에는 속하지 않는 차집합
select * from 테이블명1 left join 테이블명2 on 테이블명1.속성명 = 테이블명2.속성명 where 테이블명1.속성명 is null;
select * from dept right join emp on dept.id=emp.deptid where dept.id is null;



**not in, not exists를 이용한 차집합 연산**
not in
select 속성명1... from 테이블명1 where 속성명1 not in ( select distinct 속성명2 from 테이블명2);
┕ 주어진 속성명을 중복제거한 테이블명2의 결과에 속하지 않는(겹치지 않는) 값인 테이블명1의 속성명1 등 가져오기
not exists
select 속성명1... from 테이블명1 where not exists (
select distinct 속성명2 from 테이블명2 where 테이블명1.속성명1=테이블명2.속성명2);
┕ 주어진 속성명을 중복제거한 테이블명2의 결과에 존재하지 않는 값인 테이블명1의 속성명1 등 가져오기
아래의 차집합 연산 3개의 값은 모두 동일

UNION(합집합) : 두 테이블에 속하는 모든 데이터
select 속성명1... from 테이블명1
union(all)
select 속성명2... from 테이블명2;

대칭차집합 : 둘 중 한 집합에는 속하지만 둘 모두에는 속하지 않는 경우
select 속성명1... from (
select 속성명1... from 테이블명1
union all
select 속성명2... from 테이블명2) as 별칭(temp)
group by 속성명1... having count(*)=1; ->중복포함 합집합 결과 값이 한개인 것이므로 inner join은 제외됨
select str from (
select str from tableA
union all
select str from tableB) as temp
group by str having count(*)=1;

**not in, not exists를 이용한 대칭차집합 연산**
not in
select 속성명1... from 테이블명1 where 속성명1 not in ( select distinct 속성명2 from 테이블명2)
union all
select 속성명2... from 테이블명2 where 속성명2 not in ( select distinct 속성명1 from 테이블명1);
not exists
select 속성명1... from 테이블명1 where not exists (
select distinct 속성명2 from 테이블명2 where 테이블명2.속성명2=테이블명1.속성명1)
union all
select 속성명2... from 테이블명2 where not exists (
select distinct 속성명1 from 테이블명1 where 테이블명1.속성명1=테이블명2.속성명2);
아래의 대칭차집합 연산 3개의 값은 모두 동일

CROSS JOIN(곱집합) : 두 테이블의 모든 값을 대응시킨 것
select * from 테이블명1, 테이블명2;
select * from 테이블명1 cross join 테이블명2;
select * from 테이블명1 inner join 테이블명2 on 1=1;

참조
https://towardsdatascience.com/take-your-sql-from-good-to-great-part-3-687d797d1ede
https://www.delphican.com/showthread.php?tid=93