JOIN
- 하나 이상의 테이블에 대한 질의에 사용
- 일반적으로 기본키나 외래키를 사용해 행들을 join
방법
- inner join
: 2개의 table의 column과 column을 처리해 데이터를 출력
→ 두 table의 교집합 영역
→ where절 / on에 JOIN의 조건을 설정
: 두 table의 동일한 column 이름이 조건에 등장해서는 안 됨
→ 동일한 column 이름은 table 이름으로 명확히 구분
table이름.column이름
▶ select dname, ename from dept join emp on dept.deptno = emp.deptno;
: dept table과 emp table이 join 하고 dep table의 deptno와 emp table의 deptno가 같을 때 dname과 ename을 선택
→ on에 JOIN의 조건을 설정
▶ select dname, ename from dept join emp where dept.deptno = emp.deptno;
: dept table과 emp table이 join 하고 dep table의 deptno와 emp table의 deptno가 같을 때 dname과 ename을 선택
→ where절에 JOIN의 조건을 설정
Cartesian Product
: JOIN의 조건이 생략되거나 유효하지 않을 때 수행되는 결과
→ 모든 행이 다른 테이블의 모든 행과 JOIN됨
→ Cartisian Product를 피하기 위해선 정확한 JOIN의 조건 설정이 필요
→ dept와 emp table의 모든 행이 곱해져 출력됨
Equi Join
→ "="을 사용
→ 공통 속성의 동등 비교만 사용
▶ select * from dept, emp where dept.deptno = emp.deptno;
: dept와 emp table에서 전체를 선택하되 dept table의 deptno와 emp table의 deptno가 같은 경우를 묶어 출력
Non-Equi Join
→ "="을 사용하지 않는 JOIN
→ 정확히 일치하지 않는 column들에 대한 조건을 통해 JOIN
▶ select * from dept, emp where dept.deptno > emp.deptno;
: dept와 emp table에서 전체를 선택하되, dept table의 deptno가 emp table의 deptno보다 큰 경우로 묶어 출력
▶ select e.empno, e.ename, s.grade from emp e, salgrade s where e.sal between s.losal and s.hisal order by s.grade desc;
: emp table(별칭 e)과 salgrade table(별칭 s)에서 emp table의 sal가 salgrade table의 losal과 hisal 사이에 있을 경우 emp table의 empno, ename 그리고 salgrade table의 grade를 선택해 salgrade의 grade 기준으로 내림차순 정렬
▶ select * from emp, salgrade where sal between losal and hisal;
: emp와 salgrade table 중에서 sal이 losal과 hisal 사이인 모든 정보 출력
별칭 지정
: 결과에 등장하는 column 명이 중복되는 경우 별칭을 지정해 모호함을 피할 수 있음
▶ select * from emp, dept;
: emp와 dept table에서 모든 정보를 출력
→ emp와 dept table 모두 deptno이 존재해 column명이 중복됨
▶ select departno * 10 from dept, emp;
: dept, emp table에서 departno에 10을 곱해 출력하려고 하였으나, 오류가 발생
→ 현재 dept, emp table에 departno이 2개 존재하기 때문에 발생함
▶ select emp.deptno * 10 from dept, emp;
: dept, emp가 join된 table에서 emp의 deptno에 10을 곱해 출력
'AND' 연산자 → 다중 조건
▶ select * from dept, emp where dept.deptno = emp.deptno and sal > 1000;
: dept table의 deptno과 emp table의 deptno이 동일하고 sal이 1000 초과일 때, dept, emp table에서 전체를 출력
▶ select * from dept, emp where dept.deptno = emp.deptno and sal > 1000 or comm is null;
: dept table의 deptno과 emp table의 deptno이 동일하고 sal이 1000 초과이며 comm이 NULL값일 때, dept, emp table에서 전체를 출력
→ equi join을 사용하고 뒤에 or로 조건이 이어지며 모든 NULL값이 출력됨
▶ select * from dept, emp where dept.deptno = emp.deptno and (sal > 1000 or comm is null);
: 연산의 우선순위에 괄호()로 묶어주면 정상적으로 출력
▶ select d.dname, e.ename, e.job, e.sal from dept d, emp e where d.deptno = e.deptno order by d.dname;
: dept table(별칭 d)과 emp table(별칭 e)에서 dept table의 deptno과 emp table의 deptno이 동일한 경우 dept table의 내임, emp table의 ename, job, sal를 dept table의 dname 기준으로 오름차순 정렬
▶ select * from emp;
: emp table에서 모든 정보 출력
→ 동일한 table 내에서 ename column과 mgrname column을 결합하려고 함
▶ select a.ename, b.ename as mgrname from emp a, emp b where a.mgr = b.empno;
: emp table(별칭 a, b)에서 mgr과 empno이 동일할 때, ename과 mgrname을 출력
- outer join
: 두 table의 교집합 이외의 영역을 포함한 데이터 출력
Left Join ~ on
: 왼쪽의 table 데이터를 기준으로 오른쪽 table을 결합
→ 왼쪽의 데이터는 모두 출력하고 일치하는 오른쪽 데이터를 추가
▶ select a.ename, b.ename as mgrname from emp a, emp b where a.mgr = b.empno;
: emp table(별칭 a, b)에서 mgr와 empno이 동일할 때 ename을 출력
→ NULL값을 가진 ename KING이 emp a에 속해있기 때문에 inner join을 하면 출력되지 않음
▶ select a.ename, b.ename as mgrname from emp a left join emp b on a.mgr = b.empno;
: emp table에서 mgr와 empno이 동일할 때 ename과 매니저의 이름(ename)을 mgrname으로 출력
→ NULL값을 가진 ename KING이 출력됨
Right Join ~ on
: 오른쪽의 table 데이터를 기준으로 왼쪽의 table을 결합
→ 오른쪽의 데이터는 모두 출력하고 일치하는 왼쪽 데이터를 추가
- self join
: 하나의 table을 Join
→ 하나의 table에 다른 별칭을 주고 Join을 수행
Q1.
EMP table의 사원 이름(ename)과 dept table에 저장된 사원의 부서 이름(dname)을 출력해보자.
▶ select ename, dname from emp, dept where emp.deptno = dept.deptno;
: emp table과 dept table 모두 deptno column을 가짐
→ 동일한 column명 사용
Q2.
PRODUCT table의 모든 상품의 설명(descrip) 및 원가(stdprice)를 price table에서 가져와 출력해보자.
▶ select descrip, stdprice from price, product where price.prodid = product.prodid;
: price table과 product table 모두 prodid column을 가짐
→ 동일한 column명 사용
Q3.
PRODUCT table의 상품들 중 원가(stdprice)가 10 이하인 상품의 설명(descrip) 및 원가(stdprice)를
PRICE table에서 가져와 설명의 내림차순으로 출력해보자. (where 절 이용)
▶ select descrip, stdprice from price, product where price.prodid = product.prodid and price.stdprice <= 10 order by descrip desc;
: price table과 product table 모두 prodid column을 가짐
→ 동일한 column명 사용
Q4.
select descrip, stdprice from price, product;의 결과는 무엇일까?
▶ where, or 절이 없기 때문에 cartesian product가 생성됨
→ 전체 행의 개수는 price, product table의 행을 곱한 값
Q5.
EMP table에서 사원 이름(ENAME)과 매니저(MGR)의 이름(ENAME)을 MAGRNAME으로 출력하고,
매니저가 없다면 NULL값을 출력해보자.
▶ inner join으로 출력하면 mgrname이 NULL인 경우가 출력되지 않음
Q6.
EMP table에서 커미션(COMM)을 받는 사원들의 이름(ENAME)과 커미션(COMM)
그리고 매니저 이름(ENAME)을 MGRNAME으로 출력해보자.
▶ select a.ename, a.comm, b.ename from emp a left join emp b on a.mgr = b.empno where a.comm is not null;
→ 커미션(comm)을 받는 사원들(ename)의 매니저(mgr)가 가진 번호에 해당하는 이름을 mgrname으로 출력
'Data Base Design System' 카테고리의 다른 글
Group Functions (0) | 2021.10.15 |
---|---|
Subquery (0) | 2021.10.15 |
함수 (0) | 2021.09.30 |
연산자 (0) | 2021.09.30 |
where (0) | 2021.09.29 |