개발자 미니민의 개발스터디

[Oracle] 오라클 - 피벗 (PIVOT과 UNPIVOT)

by mini_min
[Oracle]
오라클 - 피벗 (PIVOT과 UNPIVOT)

✔️ PIVOT 절

: 열을 행으로 ROW 형태의 데이터를 COLUMN 형태로 보여주는 쿼리다.

: 컬럼의 값을 기준으로 새로운 컬럼을 도출하여 다양한 집계함수를 적용 가능하다.

 

: aggregate_function (expr) 그룹함수가 적용된 컬럼을 정의

: pivot_for_clause : 피벗의 기준이 되는 컬럼을 정의

: pivot_in_clause : 피벗 정의에 의해 정의한 컬럼의 필터링 값을 의미

 

 

-- 예제

WITH temp_table AS (
SELECT 1 cnt, 1000 price FROM DUAL UNION ALL
SELECT 2 cnt, 1050 price FROM DUAL UNION ALL
SELECT 3 cnt, 2100 price FROM DUAL UNION ALL
SELECT 1 cnt, 5500 price FROM DUAL UNION ALL
SELECT 2 cnt, 7000 price FROM DUAL UNION ALL
SELECT 3 cnt, 7000 price FROM DUAL
)
SELECT cnt, SUM(price) price
FROM temp_table
GROUP BY cnt;
WITH temp_table AS (
SELECT 1 cnt, 1000 price FROM DUAL UNION ALL
SELECT 2 cnt, 1050 price FROM DUAL UNION ALL
SELECT 3 cnt, 2100 price FROM DUAL UNION ALL
SELECT 1 cnt, 5500 price FROM DUAL UNION ALL
SELECT 2 cnt, 7000 price FROM DUAL UNION ALL
SELECT 3 cnt, 7000 price FROM DUAL
)
SELECT SUM(DECODE(cnt,1,price,0)) "1",
SUM(DECODE(cnt,2,price,0)) "2",
SUM(DECODE(cnt,3,price,0)) "3"
FROM temp_table;
💡 행열 바꾸는데 아래처럼 해도 되지만, 피벗 사용해도 괜찮음

 

 

-- 피벗으로 행열 바꾸기

WITH temp_table AS (
SELECT 1 cnt, 1000 price FROM DUAL UNION ALL
SELECT 2 cnt, 1050 price FROM DUAL UNION ALL
SELECT 3 cnt, 2100 price FROM DUAL UNION ALL
SELECT 1 cnt, 5500 price FROM DUAL UNION ALL
SELECT 2 cnt, 7000 price FROM DUAL UNION ALL
SELECT 3 cnt, 7000 price FROM DUAL
)
SELECT * FROM (
SELECT cnt, price FROM temp_table
)
PIVOT (
SUM(price) FOR cnt IN (1,2,3)
);
💡 pivot  (   출력할 값   ) FOR 행이 될 열 기준 (1,2,3)

 

 

 

🔒 문제

1) 부서별 출신도 인원수

SELECT dept, city, COUNT(*)
FROM emp
GROUP BY dept, city
ORDER BY dept;

 

 

-- 열값이던 부서를 행으로 가져가고 부서 인원수를 COUNT(dpet)

SELECT * FROM (
SELECT city, dept
FROM emp
)
PIVOT
(
COUNT(dept)
FOR dept IN (
'개발부' 개발부,
'기획부' 기획부,
'영업부' 영업부,
'인사부' 인사부,
'자재부' 자재부,
'총무부' 총무부,
'홍보부' 홍보부
)
);

 

 

 

2) 출신도에 대한 부서의 직위별 인원수

SELECT * FROM (
SELECT city, dept, pos
FROM emp
)
PIVOT
(
COUNT(dept)
FOR dept IN (
'개발부' 개발부,
'기획부' 기획부,
'영업부' 영업부,
'인사부' 인사부,
'자재부' 자재부,
'총무부' 총무부,
'홍보부' 홍보부
)
);

 

 

 

3) 월별 부서별 입사 인원수

SELECT * FROM (
SELECT TO_NUMBER(TO_CHAR(hireDate, 'MM')) 월별 , dept
FROM emp
)
PIVOT (
COUNT(월별)
FOR 월별 IN (1,2,3,4,5,6,7,8,9,10,11,12)
);
💡 행에는 '월'이 찍히도록 하고
열값은 부서를 줘서 월별 / 부서 입사 인원수를 구할 수 있다. 

 

 

 

✔️ UNPIVOT 절

: 피벗을 반대로 설정하는 것이다.

CREATE TABLE tcity AS
SELECT * FROM (
SELECT city, dept, pos
FROM emp
)
PIVOT
(
COUNT(dept)
FOR dept IN (
'개발부' 개발부,
'기획부' 기획부,
'영업부' 영업부,
'인사부' 인사부,
'자재부' 자재부,
'총무부' 총무부,
'홍보부' 홍보부
)
);
SELECT * FROM tcity;
-- 컬럼 단위를 행 단위로 변경
SELECT * FROM tcity
UNPIVOT
(
인원수
FOR 부서 IN(개발부, 기획부, 영업부, 인사부, 자재부, 총무부, 홍보부)
);

 

 

 

 

 

 

 

블로그의 프로필 사진

블로그의 정보

개발자 미니민의 개발로그

mini_min

활동하기