본문 바로가기

프로그래밍/오라클

[ORACLE] GROUP BY, HAVING _ 오라클 조인

[ORACLE] GROUP BY _ 오라클 조인 

Join의 정석    |    1. Join 선택기준

2. On 과 Where 어디 조건을 줄 것인가?

3. Join결과에서 Group By 사용법

4. 공통된 컬럼이 없는 경우 Join이 사용 가능한가? 

    가능하다면 그 기준은 어떻게 되는가?

5. Outer Join시 (Left, Right, Full Join)의 기준은?

6. 카타시안 곱은 도대체 뭐냐?



오늘은 join을 사용할 시에 group by를 언제 어떻게 사용해야하는지 공부해려고 합니다. 제가 계속 헷갈렸던 부분이 group by를 테이블을 join을 거는 중에 



문제. 사원별 가족수를 구하시오. (사원이름, 가족수, 부서명, 주소를 출력하시오.)


1. 사원들의 가족들을 구하기 위한 테이블 조인

-- 1.가족수 구하기위한 테이블 조인
  SELECT  A.ENAME "사원이름", 
          B.DNAME "부서명", 
          D.JUSO1 "주소"
    FROM  EMP A
   INNER
    JOIN  DEPT B
      ON  A.DEPTNO = B.DEPTNO
    LEFT  OUTER
    JOIN  EMPFAMILY C
      ON  A.EMPNO = C.EMPNO
    LEFT  OUTER
    JOIN  EMPDETAIL D
      ON  A.EMPNO = D.EMPNO;

이름		  부서명		    주소
-----		  ----------	----------------------
SMITH		  RESEARCH	  둔산1동 밀레니엄프라자
SMITH		  RESEARCH	  둔산1동 밀레니엄프라자
SMITH		  RESEARCH	  둔산1동 밀레니엄프라자
SMITH		  RESEARCH	  둔산1동 밀레니엄프라자
ALLEN		  SALES		    화곡2동 갤러리아
ALLEN		  SALES		    화곡2동 갤러리아
WARD		  SALES		    갈마2동 경성큰마을
WARD		  SALES		    갈마2동 경성큰마을
WARD		  SALES		    갈마2동 경성큰마을
...중략
FORD		  RESEARCH	  둔산2동 밀레니엄프라자
FORD		  RESEARCH	  둔산2동 밀레니엄프라자
ACANETJJ	RESEARCH	
JONE		  SALES	
ACANET		RESEARCH	
MILLER		ACCOUNTING	


결과를 보면, 46개의 결과가 나온 것을 볼 수 있다. 조인을 통해 가족수를 구하기 위한 테이블을 만든 것이다. 가족수 만큼 이름과 부서가 중복되어서 결과가 출력되었다. 그렇다면 사원별로 그룹을 지어주고, 숫자를 세어주면 해당 사원의 가족수가 나올 것입니다. 쿼리로 결과를 보겠습니다. 





2. 이제 집계함수를 활용해서 Group By절을 작성해보자.


각, 사원별로 Group By를 실시하여 가족수를 출력했다. 결과를 보면 14명의 사원과 그에 따른 가족수가 나타난 것을 확인 할 수 있습니다.

--사원별 가족수를 구하시오. (사원이름, 가족수, 부서명, 주소를 출력하시오.)
  SELECT  MAX(A.ENAME) AS 이름, 
          COUNT(1) AS 가족수, 
          MAX(B.DNAME) AS 부서명 , 
          MAX(D.JUSO1) AS 주소
    FROM  EMP A
   INNER
    JOIN  DEPT B
      ON  A.DEPTNO = B.DEPTNO
    LEFT  OUTER
    JOIN  EMPFAMILY C
      ON  A.EMPNO = C.EMPNO
    LEFT  OUTER
    JOIN  EMPDETAIL D
      ON  A.EMPNO = D.EMPNO
GROUP BY  A.EMPNO;

이름		  가족수     부서명		  주소
-----		  ------    ----------	----------------------
CLARK		  4	        ACCOUNTING	둔산2동 밀레니엄프라자
KING		  4	        ACCOUNTING	둔산4동 갈무리아파트
TURNER		4	        SALES		    괴정1동 밀레니엄프라자
BLAKE		  4	        SALES		    둔산2동 밀레니엄프라자
ACANET		1	        RESEARCH	
WARD		  3	        SALES		    갈마2동 경성큰마을
FORD		  4	        RESEARCH	  둔산2동 밀레니엄프라자
JONES		  4	        RESEARCH	  둔산2동 밀레니엄프라자
MARTIN		4	        SALES		    둔산5동 새둥지 아파트
SCOTT		  1	        RESEARCH	  둔산2동 밀레니엄프라자
MILLER		1	        ACCOUNTING  	
ALLEN		  2	        SALES		    화곡2동 갤러리아
ACANETJJ	1	        RESEARCH	  
ADAMS		  4	        RESEARCH	  진잠1동 밀레니엄프라자
JONE		  1	        SALES	  
SMITH		  4	        RESEARCH	  둔산1동 밀레니엄프라자
JAMES		  3	        SALES		    둔산2동 밀레니엄프라자


따라서, 여러 테이블을 Join한다고 Group By를 어디에 어떻게 써야할지 혼동하지 말자! 물론, 항상 Group By를 마지막에 쓸 수 있는 것은 아니다. 테이블의 관계를 살피고 나서 어디에 쓰면 적적할지 보는 것이다. 




3. HAVING 을 사용해서 GROUP BY에 조건을 달아보자!


GROUP BY를 걸어준 컬럼에 조건을 걸어줄 때는 HAVING절에 조건을 작성해주면 됩니다. GROUP BY 전용 WHERE 절이라 생각하면 쉽게 이해가 됩니다. 그럼, 가족수가 4명 이상인 사원만 출력보겠습니다. 

-- 가족수가 4명 이상인 사원만 출력
  SELECT  MAX(A.ENAME) AS 이름, 
          COUNT(1) AS 가족수,
          MAX(B.DNAME) AS 부서명 ,
          MAX(D.JUSO1) AS 주소
    FROM  EMP A
   INNER
    JOIN  DEPT B
      ON  A.DEPTNO = B.DEPTNO
    LEFT  OUTER
    JOIN  EMPFAMILY C
      ON  A.EMPNO = C.EMPNO
    LEFT  OUTER
    JOIN  EMPDETAIL D
      ON  A.EMPNO = D.EMPNO
   GROUP  BY  A.EMPNO
  HAVING  COUNT(1) >= 4;
이름	  가족수	  부서명		    주소
-----	  ------	----------	----------------------
CLARK	  4	      ACCOUNTING	둔산2동 밀레니엄프라자
KING	  4	      ACCOUNTING	둔산4동 갈무리아파트
TURNER	4	      SALES		    괴정1동 밀레니엄프라자
BLAKE	  4	      SALES		    둔산2동 밀레니엄프라자
FORD	  4	      RESEARCH	  둔산2동 밀레니엄프라자
JONES	  4	      RESEARCH	  둔산2동 밀레니엄프라자
MARTIN	4	      SALES		    둔산5동 새둥지 아파트
ADAMS	  4	      RESEARCH	  진잠1동 밀레니엄프라자
SMITH	  4	      RESEARCH	  둔산1동 밀레니엄프라자




추가 팁    |

서브쿼리를 이용 할 경우 Group By의 남용은 최소화 하는 것이 좋다. 


공부출처    | 

http://www.gurubee.net/lecture/1032 의 내용을 바탕으로 작성했습니다. DB를 공부하시는 분이라면 꼭 여기에 있는 강좌들을 수강해보실 것을 추천합니다.