* 조인
두 개 이상의 테이블에 정보가 나눠져 있을 경우에
여러번 질의를 해야함.
한 번의 질의로 결과를 얻을 수 있는 것이 조인이다.
* cross join
from 뒤에 테이블을 연속적으로 기술하는 것을 말함.
1번 테이블이 10개, 2번 테이블이 4개면
10*4 = 40개 row가 만들어짐.
employee 테이블 1번 row가 department row 레코드 값에 하나씩 대입하게 되는 구조임.
select * from EMPLOYEE, DEPARTMENT
* 조인 종류
equi join
non-equi join
outer join
self join
* equi 조인
두 테이블의 공통으로 존재하는 칼럼 값이 일치되는 행을 연결.
가장 많이 사용함.
select * from EMPLOYEE, DEPARTMENT where EMPLOYEE.dno = DEPARTMENT.dno
cross 조인과 동일한데 where 절에서 같은 칼럼으로 연결해줌.
* equi join + and 연산자로 이름 검색
select *
from EMPLOYEE, DEPARTMENT
where EMPLOYEE.dno = DEPARTMENT.dno
and EMPLOYEE.ename ='AAA'
* 공통적인 칼럼명이 있을 때 주의점
두 테이블에 칼럼이 중복된걸 사용하려면 에러가 나타남.
앞에 테이블명.칼럼명으로 사용
select EMPLOYEE.dno
from EMPLOYEE, DEPARTMENT
...
where EMPLOYEE.dno = DEPARTMENT.dno
* 테이블 별칭 붙이기
select 쪽과 where 쪽에서 별칭으로 활용이 가능함
select * from EMPLOYEE aaa, DEPARTMENT bbb
where aaa.dno = bbb.dno
* non-equi 조인
row 값이 특정 범위 내에 있는지 조사하는 것임
where 절에 = 이외 비교 연산자를 사용해서 만듦.
select *
from EMPLOYEE aaa, SALGRADE bbb
where aaa.SALARY between bbb.LOWSAL and bbb.HIGHSAL
select *
from EMPLOYEE aaa, SALGRADE bbb
where aaa.SALARY >= bbb.LOWSAL and aaa.SALARY <= bbb.HIGHSAL
employee 테이블의 salary 값이 lowsal과 highsal 사이에 어떤 구간에 있는지
비교해서 연결시킨다.
* 3개 테이블 조인
select * from EMPLOYEE a, DEPARTMENT b, SALGRADE c
where a.DNO = b.DNO
and a.SALARY between c.LOWSAL and c.HIGHSAL
a와 b의 dno 칼럼으로 묶고 다시 a칼럼에서 c 범위에 해당하는 row를 묶었음
a테이블을 기준으로 dno가 같은 b테이블의 row들을 붙임.
a+b가 된 테이블에 다시 c의 테이블의 row들을 붙임.
* self 조인
자기 자신과 조인을 하는 것을 말함.
같은 칼럼 내에 비교할 값이 있는 경우.
select a.ename, b.ename
from EMPLOYEE a, EMPLOYEE b
where a.MANAGER = b.ENO
a의 manager 칼럼을 기준으로 b의 eno 칼럼의 row를 조인시킴.
그 후에 검색해서 찾음
* ansi 조인
미국표준연구소인 ANSI SQL에서 제시한 표준으로
다른 DBMS와 호환을 위해서 ANSI 조인을 사용하는 것이 좋다.
1. ansi cross join
select *
from EMPLOYEE, DEPARTMENT
// 기존에는 쉼표로 구분하였음.
select *
from EMPLOYEE cross join DEPARTMENT
2. ansi inner join
equal 비교로 같은 값을 갖는 row를 출력한다.
select *
from EMPLOYEE, DEPARTMENT
where EMPLOYEE.dno = DEPARTMENT.dno
select *
from EMPLOYEE inner join DEPARTMENT
on EMPLOYEE.dno = DEPARTMENT.dno
// where가 아닌 on을 사용함
select *
from EMPLOYEE, DEPARTMENT
where EMPLOYEE.dno = DEPARTMENT.dno
and ename = 'AAA'
select *
from EMPLOYEE inner join DEPARTMENT
on EMPLOYEE.dno = DEPARTMENT.dno
where ename = 'AAA'
// on 다음에 조건을 넣을때 and가 아닌 where을 씀
3. ansi outer join
아우터 조인은 한 쪽 테이블에는 존재하고 한 쪽에는 존재하지 않는
데이터가 있을 경우에 해결하기 위한 조인이다.
self 조인의 경우, 한 쪽 테이블의 데이터가 null이라면 아예 빼버렸다.
left outer join: 왼쪽 테이블 기준으로 모두 가져오고 없는 것은 null 표시
right outer join: 오른쪽 테이블 기준으로 모두 가져오고 없는 것은 null 표시
full outer join: 같은 것은 하나로 통일, 왼쪽, 오른쪽 모두 비교함
select dno, dname into dept01
from DEPARTMENT
where dno in(10,20)
select dno, dname into dept02
from DEPARTMENT
where dno in(10,30)
// 연습용 테이블 생성
select * from dept01 inner join dept02
on dept01.dno = dept02.dno
// null이 있으면 없애고 출력 self join과 같음
select * from dept01 left outer join dept02
on dept01.dno = dept02.dno
// 왼쪽 기준 일치하지 않는 것은 null 처리
select * from dept01 right outer join dept02
on dept01.dno = dept02.dno
// 오른쪽 기준 일치하지 않는 것은 null 처리
select * from dept01 full outer join dept02
on dept01.dno = dept02.dno
// 같은 것 먼저 출력 후 왼쪽, 오른쪽 기준 일치하지 않는 것은 null 처리
* union / union all
두 쿼리의 결과를 하나의 결과로 만드는 것임.
열 개수가 같고 형식도 같아야함.
union all은 중복되도 출력되서 빠름.
union은 중복되는 값 제외함.
create table member(
id int,
name nvarchar(20),
phone nvarchar(20)
)
insert into member values (1, 'AAA', '111')
insert into member values (2, 'BBB', '222')
insert into member values (3, 'CCC', '333')
insert into member values (4, 'DDD', '444')
create table member2(
id int,
name nvarchar(20),
phone nvarchar(20)
)
insert into member2 values (2, 'BBB', '222')
insert into member2 values (4, 'DDD', '444')
insert into member2 values (6, 'FFF', '666')
insert into member2 values (7, 'GGG', '777')
테이블 2개를 생성한다.
select * from member
union
select * from member2
// 중복되는 것은 합쳐졌고 중복되지 않은 것만 붙였다.
select * from member
union all
select * from member2
// 중복되더라도 모두 붙였다.