안녕하세요. 문범우입니다.
이번 포스팅에서는 rollup, cube, case, pivot에 대해서 함께 알아보도록 하겠습니다.
먼저 이전의 글에서 만들었던 sample데이터를 통해 실습을 진행해보도록 하겠습니다.
SELECT * FROM employee;
1. ROLLUP
먼저 알아볼 함수는 ROLLUP 입니다.
ROLLUP은 GROUP BY문과 함께 사용되는 함수인데, GROUP BY로 GROUPING된 행들 데이터 총합을 나타는데 사용합니다.
즉, employee테이블에서 부서별 그리고 직급 별 급여 합과 총합을 구하기 위해서 ROLLUP이 사용될 수 있습니다.
SELECT deptNo, job, SUM(salary) 급여총합
FROM employee
GROUP BY deptNo, job with ROLLUP;
사실상 부서별 그리고 직급별 급여의 합을 구하는 것은 SUM함수를 통해서 할 수 있었습니다.
하지만 위의 결과에서 빨간색으로 음영처리해놓은 결과는 이전의 SUM함수를 통해서 얻을 수 없었습니다.
첫번째 빨간색 음영 박스가 의미하는 것은 deptNO이 10인 부서에서 모든 직급(모든 job)의 급여총합을 의미합니다.
즉, deptNO이 10인 행들끼리 job을 모두 감았다(roll up)는 의미로 생각하시면 될 것 같습니다.
그리고 우리가 GROUP BY를 deptNo, job 로 GROUPING하였기 때문에, job으로 ROLLUP된 행 3개와 deptNO으로 ROLLUP 된 마지막 행(15번째 행)까지 총 4개의 추가 행이 결과로 나오게 됩니다.
2. CUBE
이번에는 CUBE에 대해서 알아봅니다.
쉽게 생각하면 CUBE는 ROLLUP 함수의 확장 형태라고 볼 수 있습니다.
우리가 위의 예에서 deptNo, job으로 ROLLUP을 진행하니, deptNo 끼리 job으로 묶인 salary의 총합(3개 행)과 deptNo와 job으로 묶인 salary의 총합(1개행)의 추가 데이터를 얻을 수 있었습니다.
만약 ROLLUP을 job, deptNo으로 진행했다면 어떨까요?
job끼리 deptNo으로 묶인 salary의 총합(6개 행 = job의 종류가 6개)과 job과 deptNo로 묶인 salary의 총합(1개행)의 추가 데이터를 얻을 수 있습니다.
CUBE는 이렇게 GROUPING 할 때 언급한 열의 순서에 따라 나타날 수 있는 ROLLUP의 경우의 수를 모두 나타내주게 됩니다. 그럼 바로 확인해보도록 하겠습니다.
SELECT deptNo, job, SUM(salary) 급여총합
FROM employee
GROUP BY deptNo, job with CUBE;
위의 결과를 보시면 먼저 3행은 과장 직급의 급여총합을 구한 것이며, 동일하게 5행, 9행, 13행, 15행, 17행은 각 직급별 급여총합을 나타내고 있습니다.
그리고 18행은 모든 deptNo와 job의 급여 총합을 나타내주고 있으며, 19행, 20행, 21행은 deptNo별 급여총합을 나타내고 있습니다.
위의 쿼리문을 아래와 같이 하면 행의 순서는 바뀔 수 있지만 결과는 동일합니다
SELECT deptNo, job, SUM(salary) 급여총합
FROM employee
GROUP BY job, deptNo with CUBE;
3. CASE
이번에 알아볼 CASE문은 C언어나 Java와 같은 프로그래밍 언어에서 사용되는 if ~ else ~ 문 또는 switch 문과 개념적으로 동일합니다.
기본적인 형식은 아래와 같습니다.
CASE when 조건식1 then 결과 1
when 조건식1 then 결과2
...
[ELSE 결과]
END [AS 칼럼 명]
여기서 대괄호로 표시된 것들은 생략할 수 있습니다.
CASE문은, 우리가 employee 테이블에서 부서별로 부서명을 직접 나타내고 싶을 때와 같은 경우에 사용할 수 있습니다. 부서번호가 10인 경우 전산부, 20인 경우 인사부, 30인 경우 경리부, 40인 경우 영업부로 나타내고 이 외에는 미정이라고 나타내보도록 합시다.
SELECT empName, deptNo,
CASE WHEN dpetNo = 10 THEN '전산부'
WHEN deptNo = 20 THEN '인사부'
WHEN deptNo = 30 THEN '경리부'
WHEN deptNo = 40 THEN '영업부'
ELSE '미정'
END AS 부서명
FROM employee;
위와 같이 우리가 조건을 설정한 대로 부서명이 올바르게 출력되었습니다.
조건식에는 범위에 대한 조건도 설정할 수 있습니다.
만약 부서번호가 20이하인 경우는 부서위치가 1층, 20초과인 경우에는 부서위치가 2층인 것으로 나타내고자 하면 다음과 같이 할 수 있습니다.
SELECT empName, deptNo,
CASE WHEN deptNo <= 20 THEN '1층'
WHEN deptNo > 20 THEN '2층'
END AS 부서위치
FROM employee;
4. PIVOT / UNPIVOT
마지막으로 알아볼 것은 PIVOT과 UNPIVOT입니다.
먼저 PIVOT에 대해서 알아보도록 하겠습니다.
PIVOT은 행으로 되어 있는 데이터를 열로 변환해서 표현하는 함수입니다.
우리가 가지고 있는 employee 테이블에서 열을 deptNo과 각 직급으로 나타내어 그 값을 표현하려면 어떻게 해야 할까요? 기존의 직급 데이터는 'job'이라는 속성에 행으로써 존재 했습니다. 하지만 사원, 부장 과 같이 행으로 되어있던 데이터를 열로 나타내려면 PIVOT을 사용하면 됩니다.
PIVOT문의 기본 형태는 다음과 같습니다.
SELECT [PIVOT열1], [PIVOT열2], ...
FROM 테이블명
PIVOT(나타내고자하는 값, FOR 행->열로 바꿀 열 IN ([PIVOT열1], [PIVOT열2], ...)) as 별칭
PIVOT문은 조금 어려울 수 있기 때문에 바로 실제 쿼리를 보면서 이해하시는 것을 추천드립니다.
위에서 이야기한 바를 쿼리로 나타내면 다음과 같습니다.
SELECT deptNo, [사원], [대리], [과장], [부장], [차장], [사장]
FROM employee
PIVOT(SUM(salary) FOR job In([사원], [대리], [과장], [부장], [차장], [사장])) AS job
ORDER BY deptNo;
위와 같이 행으로 되어있던 값을 열로 나타내어 테이블의 형태를 재구축 할 수 있습니다.
UNPIVOT과 같은 경우도 PIVOT과 활용법이 동일하지만 PIVOT이 행->열의 방식이었다면 UNPIVOT은 열->행의 방식인 것만 고려하면 됩니다.
'Database > MS SQL' 카테고리의 다른 글
[MS SQL Server] #11_ IN / EXISTS / NOT IN / NOT EXISTS 비교 (29) | 2019.05.16 |
---|---|
[MS SQL Server] #10_순위 함수(RANK, DENSE_RANK, ROW_NUMBER, NTILE) (2) | 2019.05.15 |
[MS SQL Server] #8_집계함수, GROUP BY, HAVING (0) | 2019.04.21 |
[MS SQL Server] #7_LIKE 연산, ORDER BY, TOP n (0) | 2019.04.16 |
[MS SQL Server] #6_SELECT문에 WHERE절 사용하기 (2) | 2019.04.16 |