본문 바로가기

📚Study Note/ORACLE

[ ORACLE ] GROUP BY GROUP BY ROLLUP() GROUPING()

SELECT DEPTNO, SUM(SAL)
FROM EMP
GROUP BY DEPTNO
ORDER BY DEPTNO;
--===>>
/*
10	8750
20	10875
30	9400*/







SELECT  DEPTNO "부서번호", SUM(SAL) "급여합"
FROM EMP
GROUP BY ROLLUP(DEPTNO);
/*
10	    8750
20	    10875
30	    9400
(NULL)	29025*/ --→ 전체 합까지 나온다.



SELECT *
FROM TBL_EMP;


-- ● 데이터 입력
INSERT INTO TBL_EMP VALUES
(8001, '수지', 'CLERK', 7566, SYSDATE, 1500, 10, NULL);
--==>> 1 행 이(가) 삽입되었습니다.

INSERT INTO TBL_EMP VALUES
(8002, '아이유', 'CLERK', 7566, SYSDATE, 1000, 10, NULL);
--==>> 1 행 이(가) 삽입되었습니다.


INSERT INTO TBL_EMP VALUES
(8003, '정유미', 'SALESMAN', 7698, SYSDATE, 2000, NULL, NULL);
--==>> 1 행 이(가) 삽입되었습니다.

INSERT INTO TBL_EMP VALUES
(8004, '이제훈', 'SALESMAN', 7698, SYSDATE, 2500, NULL, NULL);
--==>> 1 행 이(가) 삽입되었습니다.


INSERT INTO TBL_EMP VALUES
(8005, '한지민', 'SALESMAN', 7698, SYSDATE, 1000, NULL, NULL);
--==>> 1 행 이(가) 삽입되었습니다.

/*
7369	SMITH	CLERK	    7902    1980-12-17	800		        20
7499	ALLEN	SALESMAN	7698	1981-02-20	1600	300	    30
7521    WARD	SALESMAN	7698	1981-02-22	1250	500	    30
7566	JONES	MANAGER	    7839	1981-04-02	2975		    20
7654	MARTIN	SALESMAN	7698	1981-09-28	1250	1400	30
7698	BLAKE	MANAGER	    7839	1981-05-01	2850		    30
7782   	CLARK	MANAGER	    7839	1981-06-09	2450		    10
7788	SCOTT	ANALYST	    7566	1987-07-13	3000		    20
7839	KING	PRESIDENT		    1981-11-17	5000		    10
7844	TURNER	SALESMAN	7698	1981-09-08	1500	0	    30
7876	ADAMS	CLERK	    7788	1987-07-13	1100		    20
7900    JAMES	CLERK	    7698	1981-12-03	950		        30
7902    FORD	ANALYST	    7566	1981-12-03	3000		    20
7934	MILLER	CLERK	    7782    1982-01-23	1300		    10
8002    아이유	CLERK	    7566	2021-03-30	1000	0	    NULL
8001    수지  	CLERK	    7566	2021-03-30	1500	10	    NULL
8003    정유미	SALESMAN	7698	2021-03-30	2000		    NULL
8004    이제훈	SALESMAN	7698	2021-03-30	2500		    NULL
8005    한지민	SALESMAN	7698	2021-03-30	1000		    NULL	
*/




COMMIT;
--==>>커밋 완료.



SELECT  DEPTNO "부서번호", SUM(SAL) "급여합"
FROM TBL_EMP
GROUP BY DEPTNO;
/*
30	9400
널	8000
20	10875
10	8750
*/



SELECT  DEPTNO "부서번호", SUM(SAL) "급여합"
FROM TBL_EMP
GROUP BY ROLLUP(DEPTNO);
-        -------
/*
부서번호  급여합
10	    8750
20	    10875
30	    9400
NULL	8000       -- 부서번호가 NULL인 데이터들끼리의 합
NULL   	37025*/    -- 모든 부서의 급여 합

-- 문제 ::: 위에서 조회한 내용을 아래와 같이 표시하려면?
/*
부서번호  급여합
10	     8750
20	     10875
30	     9400
인턴	     8000       -- 부서번호가 NULL인 데이터들끼리의 합
모든부서  37025*/    -- 모든 부서의 급여 합

SELECT CASE DEPTNO WHEN NULL THEN '인턴'
                   ELSE DEPTNO
       END "부서번호"
FROM TBL_EMP;
--==>>
/*
ORA-00932: inconsistent datatypes: expected CHAR got NUMBER
00932. 00000 -  "inconsistent datatypes: expected %s got %s"
*Cause:    
*Action:
864행, 29열에서 오류 발생*/

SELECT CASE DEPTNO WHEN NULL THEN '인턴'
                   ELSE TO_CHAR(DEPTNO)
       END "부서번호"
FROM TBL_EMP;
/*
20
30
30
20
30
30
10
20
10
30
20
30
20
10
(NULL)
(NULL)
(NULL)
(NULL)
(NULL)
*/


SELECT CASE WHEN DEPTNO IS NULL THEN '인턴'
                   ELSE TO_CHAR(DEPTNO)
       END "부서번호"
FROM TBL_EMP;
/*
20
30
30
20
30
30
10
20
10
30
20
30
20
10
인턴
인턴
인턴
인턴
인턴*/


SELECT CASE WHEN DEPTNO IS NULL THEN '인턴'
                   ELSE TO_CHAR(DEPTNO)
       END "부서번호"
       ,SUM(SAL) "급여합"
FROM TBL_EMP
GROUP BY ROLLUP(DEPTNO);
/*
10	    8750
20	    10875
30	    9400
인턴	8000
인턴	37025*/


SELECT NVL2(DEPTNO,TO_CHAR(DEPTNO),'인턴') "부서번호", SUM(SAL) "급여합"
FROM TBL_EMP
GROUP BY ROLLUP(DEPTNO);
/*
10	    8750
20	    10875
30	    9400
인턴	8000
인턴	37025*/

-- ※ GROUPING()

SELECT DEPTNO "부서번호", SUM(SAL) "급여합", GROUPING(DEPTNO) "그루핑결과"

FROM TBL_EMP
GROUP BY ROLLUP(DEPTNO);
/* 부서번호  급여합  그루핑결과
    10	    8750	        0
    20	    10875	        0
    30	    9400        	0
    null    8000	        0
    null    37025	        1*/ --GROUNPING() 은 몇 레벨로 묶음처리를 했는지 보여줌





SELECT CASE WHEN DEPTNO IS NULL AND GROUPING(DEPTNO)=0 
            THEN '인턴'
            WHEN DEPTNO IS NULL AND GROUPING(DEPTNO)=1 
            THEN '모든부서'
            ELSE TO_CHAR(DEPTNO)
       END "부서번호"
       ,SUM(SAL) "급여합"
FROM TBL_EMP
GROUP BY ROLLUP(DEPTNO);
/*
10	        8750
20	        10875
30	        9400
인턴	    8000
모든부서	37025
*/

 

정리하자면 월급합계를 알고 싶을 때 

GROUP BY 부서  ▶ 부서 합계를 보여준다.

GROUP BY ROLLUP(부서) ▶ 부서 별 합계 뿐만 아니라 전체 부서의 합계또한 보여준다. 

 

ROLLUP의 경우 

부서                                             합계

NULL 8000 (부서가 NULL인 경우)
NULL 37025  (전체부서의 합인데 지정을 안해줘서 NULL로 나옴 )

이 NULL NULL 두 개를 <부서가 없는 경우 > <전체부서> 이렇게 구분해주기 위해서 

 

GROUPING(부서) ▶ 각각의 부서를 묶은 경우 0 이지만 , 모든 부서를 통틀어 묶은 경우 1이 반환되어 

위 두 개의  NULL을 구분 가능하게 해준다.