날짜 : 2021-06-29
태그 : oracle SQL join 조인
메모
JOIN (조인)
조인을 이해하려면 왜 조인개념이 등장했는지 알면 편한데 .
우리가 여러 테이블에 데이터가 따로 따로 있는경우 여러번의 select 를 거쳐 다시 그 결과로 다른 테이블의
정보를 찾아보곤했었다. 그런데 이번거로움을 조인을이용하면 한번의 명령으로 여러테이블의 정보들을 연결하여
우리가 원하는 정보를 찾을 수 있게 된다.
1.1 조인
아래에 설명된 모든 예제는 oracle 기준으로 작성되었습니다.
select *
from emp,dept;
--이렇게 조건없이 두개의 테이블을 불러오는것도 가능. 하지만 가독성이 매우떨어지고 불필요한정보가 여기저기붙어있다.
select * from emp,dept
where ename='KING';
--ename 이 KING인 모든정보를 emp와 dept 테이블에서 찾아볼수 있다.
2.equi 조인
select *from emp ,dept
where emp.deptno = dept.deptno;
--join 의 개념. 여러개의 테이블에 공통되는 컬럼을이용하여 select을 여러번거쳐야하는것을
--한번만에 출력할 수 있게하는 기능. where절이없다면 조인조건이없는 cartesian product라고한다.(잘안쓰임)
select ename , empno ,loc , deptno
from emp, dept
where emp.deptno = dept.deptno;
--만약 emp 테이블과 dept 테이블에 공통으로 deptno라는 컬럼이있다면 select절에서 에러가나게된다.
--겹치는 컬럼은 따로 어떤걸쓸건지 정해줘야한다
select ename , empno, loc , emp.deptno
from emp, dept
where emp.deptno = dept.deptno;
--이렇게
select emp.empno , ename , dname , dept.loc
from emp , dept
where emp.deptno = dept.deptno;
--여기서 유일컬럼은(컬럼이름이겹치지않는것) ename , dname , loc , empno 인데
--저렇게 테이블이름.컬럼이름 이런형식으로 써도 상관은없다. 안써도상관없고
--하지만 겹치는 컬럼은 반드시 저런형식으로 사용해야한다.
select e.empno , e.ename , dname , loc
from emp e , dept d
where e.deptno = d.deptno;
-- 테이블에도 별칭을 줄 수 있다 . 여기서주의할점은 셀렉트에서도 테이블별칭을사용해야한다.
-- 별칭을쓰면 emp.empno (X) 이렇게 사용못한다. 반드시 별칭을사용해야함.
3.조건추가
select e.empno , e.ename , dname , loc , e.deptno
from emp e , dept d
where e.deptno = d.deptno
and ename = 'KING';
--and 를 사용하여 검색조건을 추가해서 검색할 수 도 있다.
--조인에서의 where 라고 생각하면된다.
select e.empno , e.ename , dname , loc , e.deptno
from emp e , dept d
where e.deptno = d.deptno
and dname = 'SALES';
--dept테이블에서 부서이름이 SALES 인 사람들의 데이터
4.Non-equi 조인
select e.ename ,e.sal ,s.grade
from emp e, salgrade s
where e.sal between s.losal and s.hisal
and e.ename = 'KING';
-- non equi조인은 조건이 반드시일치하지않아도 범위에 포함되는경우를 조회한다.의 예 동등이아니라 범위를비교하는것. = 이외의 부등 > < 등을 이용할때
--between 을 이용하여 losal 과 hisal 사이에있는 sal값에따라 등급을 나타낸다.
select e.ename ,e.sal ,s.grade
from emp e, salgrade s
where e.sal between s.losal and s.hisal
and s.grade = '2';
--salgrade는 연봉의 등급범위 테이블이다. , grade 는 연봉의등급컬럼임
select s.grade , count(*)
from emp e , salgrade s
where e.sal between s.losal and s.hisal
and s.grade=2
group by s.grade;
--count 와 혼합사용
select e.ename , d.dname, d.deptno , hiredate
from emp e , dept d
where e.deptno=d.deptno and to_char(hiredate,'YYYY') = '1981';
--1981 년도에 입사한 사원의 내용추출
--equi 조인과 조건을 추가하여 데이터를 검색
select d.dname 부서명, count(*) 인원수
from emp e, dept d
where e.deptno=d.deptno and
to_char(e.hiredate,'YYYY') < 2005
group by d.dname;
--조인 + 연도조건 + 부서별그루핑 혼합.
****
**4.1 3개의테이블 조인**
select e.ename , sal , dname , s.grade
from emp e, dept d, salgrade s
where e.sal between s.losal and s.hisal
and e.deptno=d.deptno
order by grade asc;
--3개의 테이블 조인 + 동등과 부등혼합.
5. Self 조인
select e.ename 사원이름 , e.mgr 관리자번호 , m.empno 관리자의사원번호 , m.ename 관리자의이름
from emp e,emp m
where e.mgr=m.empno ;
--같은 테이블안에서의 조인인 self join 헷갈리지않기위해 alias 를 꼭사용해야한다.
--KING이 빠져있는걸볼수있다. KING의 mgr= null 이기때문에 데이터에서 자동으로빠졌다.
select e.ename,e.mgr, m.empno 관리자사원번호 ,m.ename 관리자이름,
m.deptno 관리자부서번호 , dname
from emp e,emp m ,dept d
where e.mgr=m.empno
and m.deptno=d.deptno
and e.empno=7902;
--이름이 frod인=(사원번호가7902인) 사원의 관리자번호 ,
-- 관리자 이름과 포드가 속한부서의 이름을 select한 내용
select e.ename 사원이름,m.empno 관리자번호 , m.ename 관리자이름,
dname 사원부서이름,e.deptno
from emp e, emp m, dept d
where e.mgr=m.empno
and e.deptno=d.deptno
and e.ename='FORD';
--이름이 FORD인 사원의 관리자번호, 관리자 이름과 포드가 속한 부서의 이름을 select
select e.ename 사원이름 ,e.mgr,m.ename,m.mgr, mm.ename 관리자의관리자이름 ,
mm.empno 관리자의관리자번호
from emp e, emp m , emp mm
where e.mgr=m.empno and m.mgr=mm.empno
and e.ename = 'FORD';
-- self 조인 활용 . 사원이름에서 관리자의 관리자 정보를 찾는내용
--조금 복잡하지만 같은emp테이블에서 e 와 m , mm 으로 Alias를 준후 적절하게 조인을 하면완성.
select e.ename 사원이름 , e.mgr , m.ename , m.mgr ,
mm.ename , mm.mgr
from emp e, emp m ,emp mm
where e.mgr=m.empno
and m.mgr=mm.empno
and e.ename = 'MILLER';
--이름이 'MILLER'인 사원의 관리자 정보와 관리자의 관리자 정보를 추출.
select *
from 부서테이블 , 회사원정보테이블
where 부서테이블.department_no=회사원정보테이블.department_no
and department_name ='판매' and 입사일컬럼 like '01%';
--부서가 판매부서 이고 01년에 입사한 회사원의 데이터 검색
--세번째 and 뒤에 to_char(입사일컬럼,'YY')= '01'; 으로 변경해도 작동한다.
select 회사원이름컬럼
from 부서테이블 , 회사원정보테이블
where 부서테이블.department_no=회사원정보테이블.department_no
and department_name = '인사' and 휴직여부컬럼 = 'Y'
and substr(회사원주민등록컬럼,8,1)=2;
--인사과에 있는 회사원중 현재 휴직중인 여 사원을 검색
생각 (질문)
출처 (문헌)
학원에서 준 바인딩 책임