프로그래밍/Database

[오라클] Join문과 Aggregation

Jay22 2017. 3. 30. 10:45
반응형

이전에는 select에 대해 자세히 알아보았다. 그 때에 쓴 테이블들을 똑같이 써서 join문을 공부해보자.


Join


조인이란 둘 이상의 테이블을 합쳐서 하나의 큰 테이블로 만드는 방법

필요성 : 관계형 모델에서는 데이터의 일관성이나 효율을 위하여 데이터의 중복을 최소화한다.

fk를 이용하여 참조한다.


여기서 테이블부터 만드는 과정이 초반에 있으므로 파일을 다운받고 참조해서 테이블을 셋팅하자.

http://pjh3749.tistory.com/156


그럼 시작하기 전에 emp테이블과 dept테이블의 칼럼부터 확인해보자.



emp테이블





dept테이블




그리고 어떤 join들이 있는지 살펴보자.


Cross Join (Cartesian Product) : 모든 가능한 쌍이 나타남

Inner Join : Join 조건을 만족하는 튜플만 나타남

Outer Join : Join 조건을 만족하지 않는 튜플 (짝이 없는 튜플)도 null과 함께 등장함

Theta Join : 조건에 의한 조인

Equi Join : Theta Join + 조건이 Equal(=)

Natural Join : Equi-Join & 동일한 Column명 합쳐짐

Self Join : 자기 자신과 조인




# Cartesian product


두 테이블을 카티전 프로덕트를 하면 교차로 다 곱해져셔 나온다. CROSS JOIN이라고도 한다. 안쓰인다. 그냥 보고가자.


SELECT * FROM emp, dept; 

SELECT * FROM emp CROSS JOIN dept; 






# Equi Join


SELECT * FROM dept, emp

WHERE dept.deptno = emp.deptno;



equal조건에 의해서 결과가 나오지만 동일한 컬럼은 합쳐지지 않고 저렇게 언더바 치고 1 로 나온다.



# Natural Join


 SELECT * FROM dept NATURAL JOIN emp;



합쳐지면서 동일한 컬럼은 그냥 하나로 치기 때문에 없다.



# Non-Equi Join


조건이 equal이 아닌 조인. theta조인이라고 부름


select e.ename, e.job, e.sal, s.grade from emp e, salgrade s where e.sal between s.losal and s.hisal






# Outer Join


SELECT ename, dname FROM emp e, dept d WHERE e.deptno (+)= d.deptno; 

SELECT ename, dname FROM dept LEFT OUTER JOIN emp USING (deptno);



지금 보면 dept left outer join emp 이다. 먼저나온테이블이 기준 테이블이다. 즉, dept를 쫙 조회를 하고 거기에 emp를 갖다 붙이는 것이다. 테이블 내용을 살펴보면 dept에는 emp애들이 없는 부서넘버 40을 가지고 있다. 그럼 40까지 표현을 해야되는데 emp에 없으므로 15line처럼 null로 나온다. 즉 row수는 기준 테이블에의해 결정된다.


right outer join으로만 바꿔보면 그 반대임을 알 수 있다.






# Self Join


자기자신에 조인하는 것이다.


select e.ename follower, m.ename manager from emp e, emp m where e.mgr = m.empno;


follower는 부사수 manager는 사수라고 보면 되겠다. 즉 사수-부사수 목록을 출력한다. 이런식으로 조인하면 사수 혹은 부사수가 없는 인원은 출력되지 않을 것이다.








select e.ename follower, m.ename manager from emp e, emp m where e.mgr = m.empno (+);


이거는 꼬리가 붙었다. (+) 가 붙었는데 붙은쪽이 나중에 계산된다. 무슨 말이냐면 m.empno가 조인이 되는 것이므로 e가 먼저 조회된다. 그러면 모든 e.ename이 다 나온상태에서 m이 붙는 것이다. 바로 위에 것은 짝이 없으면 안나왔다. 그런데 이것은 e의 ename이 다 출력되야 하므로 사수가 없는 KING까지 나온다. 사수는 NULL이다.










저 null이 보기싫다. 


select e.ename follower, NVL(m.ename, 'I am Boss') manager from emp e, emp m where 4 e.mgr = m.empno (+);






전부 다 뽑아 보자. 그러면 full outer join 을 하면 양쪽 테이블의 짝이 없는 모든 애들을 다 가져올 것이다.


 select NVL(e.ename, 'I have no follower') follower, NVL(m.ename, 'I am Boss') manager from emp e FULL OUTER JOIN emp m ON e.mgr = m.empno;


\







## Aggregation


# COUNT


SELECT count(*) FROM emp;  


emp 의 총 row 갯수를 반환한다.


14


SELECT count(comm) FROM emp; 


comm의 총 갯수를 반환하지만 null 값은 건너뛴다.


4


SELECT count(job) FROM emp; 


총 job 갯수 중복안따진다


14


SELECT count(DISTINCT job) FROM emp;

직업 종류 갯수를 나타낸다.


5



#SUM


select sum(sal) from emp;

월급의 합이다.




SELECT sum(DISTINCT sal) FROM emp;


중복된 월급은 날려버리고 계산한다...









# AVG


SELECT avg(comm) FROM emp;


comm의 평균이다. 근데 이건 null값을 제외한 값들의 평균이다. 나눌때도 null값갯수는 제외시킨다.




SELECT sum(comm)/count(*) FROM emp; 


이거는 전체카운트로 나눴으므로 null값이 포함되어 있는 갯수로 나눈것이다.



SELECT sum(comm)/count(comm) FROM emp; 


이것은 count도 null값 제외했으므로 첫 번째와 똑같은 값이 나올 것이다.



도움이 되셨다면 공감눌러주시고 궁금한점 댓글 남겨주세요~




반응형