데이터베이스
PIVOT , UNPIVOT
ssseung
2021. 5. 16. 22:27
PIVOT
PIVOT 은 회전시킨다는 의미를 갖고 있다.
PIVOT 절은 행을 열로 회전시킨다.
PIVOT [ XML ]
(
aggregate_function (expr) [[AS] ALIAS] // 집계할 열을 지정
[,aggregate_function (expr) [[AS] ALIAS] ]
FOR { column | (column[,column..])} // PIVOT 할 열을 지정
IN ({ { {expr | (expr[,expr]..)} [[AS] alias ]} // PIVOT 할 열 값을 지정
| subquery
| ANY [,ANY]
})
)
aggregate function : 집계할 열을 지정
FOR : PIVOT 할 열을 지정
IN : PIVOT 할 열 값을 지정
SELECT *
FROM (
SELECT JOB, DEPTNO, SAL
FROM EMP
PIVOT ( SUM(SAL) // 집계할 열을 지정
FOR DEPTNO // PIVOT할 열을 지정
IN (10,20,30) // PIVOT할 열 값을 지정
)
ORDER BY 1;
===============================================
JOB 10 20 30
----- ---- ---- ----
ANALYST 6000
CLERK 1300 1900 950
MANAGER 2450 2975 2850
PRESIDENT 5000
SALESMAN 5000
집계함수과 IN 절에 지정한 별칭에 따라 아래와 같은 규칙으로 열 명이 부여된다.
집계함수와 IN 절 모두 별칭을 지정하는 것이 바람직하다.
10 | 10 as D10 | |
SUM(SAL) | 10 | D10 |
SUM(SAL) AS sal | 10_sal | D10_sal |
조건문 부여 예시
SELECT JOB, D20_SAL
FROM (
SELECT JOB, DEPTNO, SAL
FROM EMP
PIVOT ( SUM(SAL) AS SAL
FOR DEPTNO
IN (10 AS D10, 20 AS D20, 30 AS D30)
WHERE D20_SAL > 2500
)
ORDER BY 1;
===============================================
JOB D20_SAL
----- --------
ANALYST 6000
MANAGER 2975
다수의 집계함수 사용 예시
SELECT JOB, D20_SAL
FROM (
SELECT JOB, DEPTNO, SAL
FROM EMP
PIVOT ( SUM(SAL) AS SAL
,COUNT(*) AS CNT
FOR DEPTNO
IN (10 AS D10, 20 AS D20, 30 AS D30)
)
ORDER BY 1;
===============================================
JOB D10_SAL D10_CNT D20_SAL D20_CNT
----- ------- ------- ------- -------
ANALYST 0 6000 2
CLERK 1300 1 1900 2
MANAGER 2450 1 2975 1
...
FOR 절에 다수의 열 기술 예지
SELECT JOB, D20_SAL
FROM (
SELECT TO_CHAR(HIREDATE,'YYYY') AS YYYY, JOB, DEPTNO, SAL
FROM EMP
PIVOT ( SUM(SAL) AS SAL
,COUNT(*) AS CNT
FOR ( DEPTNO, JOB )
IN ( (10,'ANALYST') AS D10A
,(10,'CLERK') AS D10C
,(20,'ANALYST') AS D20A
,(20,'CLERK') AS D20C )
)
ORDER BY 1;
===================================================
YYYY D10A_SAL D10A_CNT D10C_SAL D10C_CNT D20A_SAL D20A_CNT D20C_SAL D20C_CNT
----- -------- -------- -------- -------- -------- -------- -------- --------
1980
1981 ...............
1982
PIVOT 대신 집계함수와 CASE 표현식 사용
================================================================
CASE 문
================================================================
SELECT JOB
, SUM (CASE DEPTNO WHEN 10 THEN SAL END) AS D10_SAL
, SUM (CASE DEPTNO WHEN 20 THEN SAL END) AS D20_SAL
, SUM (CASE DEPTNO WHEN 30 THEN SAL END) AS D30_SAL
FROM EMP
GROUP BY JOB
ORDER BY JOB;
================================================================
PIVOT 절
================================================================
SELECT *
FROM (
SELECT JOB, DEPTNO, SAL
FROM EMP
PIVOT ( SUM(SAL)
FOR DEPTNO
IN (10 AS D10, 20 AS D20, 30 AS D30)
)
ORDER BY 1;
================================================================
JOB D10_SAL D20_SAL D30_SAL
----- ------- ------- -------
ANALYST 6000
CLERK 1300 1900 950
MANAGER 2450 2975 2850
PRESIDENT 5000
SALESMAN 5000
UNPIVOT
UNPIVOT 절은 열을 행으로 회전시킨다.
UNPIVOT [ { INCLUE | EXCLUDE } NULLS ]
( { column | (column[,col..]..) } // UNPIVOT 된 값이 들어갈 열을 지정
FOR { column | (column[,col..]) } // UNPIVOT 된 값을 설명할 값이 들어갈 열을 지정
IN ( // UNPIVOT할 열과 설명할 값의 리터럴 값을 지정
{ column | (column[,col..]) } AS { literal | literal[,literal]..}
,[{ column | (column[,col..]) } AS { literal | literal[,literal]..}]
)
)
UNPIVOT column : UNPIVOT 된 값이 들어갈 열을 지정
FOR 절 : UNPIVOT 된 값을 설명할 값이 들어갈 열을 지정
IN 절 : UNPIVOT할 열과 설명할 값의 리터럴 값을 지정
//테이블 T1 내부
SELECT * FROM T1 ORDER BY JOB;
===========================================
JOB D10_SAL D20_SAL D30_SAL
----- ------- ------- -------
ANALYST 6000
CLERK 1300 1900 950
MANAGER 2450 2975 2850
PRESIDENT 5000
SALESMAN 5000
SELECT JOB, DEPTNO, SAL
FROM T1
UNPIVOT (
SAL // UNPIVOT 된 값이 들어갈 열을 지정
FOR DEPTNO // UNPIVOT 된 값을 설명할 값이 들어갈 열을 지정
IN (D10_SAL, D20_SAL) // UNPIVOT할 열과 설명할 값의 리터럴 값을 지정
)
ORDER BY 1,2;
===================================================
JOB DEPTNO SAL
====== ====== ====
ANALYST D20_SAL 6000
CLERK D10_SAL 1300
CLERK D20_SAL 1900
UNPIVOT 도 PIVOT 과 마찬가지로 다수의 집계 함수를 지원하고 다수의 열을 가질 수 있다.
UNPIVOT 을 사용할 수 없는 경우 카디션 곱을 통해 수행할 수 있다.
UNPIVOT 랑 열의 개수만큼 행을 복제하고, CASE 표현식으로 UNPIVOT 랑 열을 선택하는 방식이다.
SELECT A.JOB
, CASE B.LV WHEN 1 THEN 10 WHEN 2 THEN 20 END AS DEPTNO
, CASE B.LV WHEN 1 THEN A.D10_SAL WHEN 2 THEN A.D20_SAL END AS SAL
, CASE B.LV WHEN 1 THEN A.D10_CNT WHEN 2 THEN A.D20_CNT END AS CNT
FROM T1 A
,( SELECT LEVEL AS LV FROM DUAL CONNECT BY LEVEL <=2 ) B
ORDER BY 1, 2;
===================================================
JOB DEPTNO SAL CNT
====== ====== ==== ====
ANALYST 10 0
ANALYST 20 6000 0
CLERK 10 1300 2
CLERK 20 1900 1
출처
SQL 전문가 가이드 - 한국데이터산업진흥원
반응형