본문 바로가기

DB/Oracle

pivot (오라클11g)

반응형

프로젝트를 진행하다보면 통계를 뽑아서 출력해야되는 경우가 생긴다.

아래는 예시 데이터이다

A1 는 운동한 종목, A2는 요일, A_CNT는 세트 수 이다

 

데이터를 보면 운동한 종목과 요일별로 데이터가 들어가있다.

저 데이터를 종목별로 어느요일에 몇 세트를 했는지 표시하기 위해 어떻게 해야할까

 

가장 먼저 떠오르는건 반복문이다.

저 데이터를 통째로 가져와서 for 문을 돌며 해당 요일에 맞는 데이터가 있으면 배열같은곳에 저장하고...

다시 날짜별로 저장해둔 데이터를 반복하여 출력하는 식으로도 할 수 있을것이다.(별로다)

 

 

두번째로는 각 종목별이나 날짜별로 조건을 줘서 데이터를 가져오는 방식이다.

출력하는데에는 1번 방법보다는 편할수 있으나 DB를 여러번 SELECT 하게 되는 문제점이 있다.

 

 

세번째로는 DECODE를 활용하는것이다.

오라클 11 버전 이전에는 pivot이 없었기에 저렇게 열을 행으로 바꿔야하는 경우 사용했었다.

SELECT A1,
       SUM(DECODE(A2, 'MONDAY', A_CNT, 0))    AS MONDAY,
       SUM(DECODE(A2, 'TUSEDAY', A_CNT, 0))   AS TUSEDAY,
       SUM(DECODE(A2, 'WENDSEDAY', A_CNT, 0)) AS WENDSEDAY,
       SUM(DECODE(A2, 'TURTHDAY', A_CNT, 0))  AS TURTHDAY,
       SUM(DECODE(A2, 'FRIDAY', A_CNT, 0))    AS FRIDAY,
       SUM(DECODE(A2, 'SATURDAY', A_CNT, 0))  AS SATURDAY,
       SUM(DECODE(A2, 'SUNDAY', A_CNT, 0))    AS SUNDAY
FROM zt_phs_pivot
group by A1
order by A1

 

종목을 그룹으로 묶어 사용하는 식이다.

DECODE 사용 결과값

 

 

이제 이걸 좀 편하게? 바꿀수 있는 pivot을 사용해보자

SELECT *
  FROM ( 피벗 대상 쿼리문 )
 PIVOT ( 그룹합수(집계컬럼) FOR 피벗컬럼 IN (피벗컬럼값 AS 별칭 ... )

pivot 의 기본 문법

예시 데이터에 적용

SELECT A1,
       NVL(월,0) AS 월,	-- NULL 일 경우 NVL을 사용하여 0 표기
       NVL(화,0) AS 화,
       NVL(수,0) AS 수,
       NVL(목,0) AS 목,
       NVL(금,0) AS 금,
       NVL(토,0) AS 토,
       NVL(일,0) AS 일
FROM (select A1, A2, A_CNT from zt_phs_pivot)
    PIVOT ( SUM(A_CNT)
    FOR A2 IN (
        'MONDAY' AS 월,
        'TUSEDAY' AS 화,
        'WENDSEDAY' AS 수,
        'TURTHDAY' AS 목,
        'FRIDAY' AS 금,
        'SATURDAY' AS 토,
        'SUNDAY' AS 일)
    )
order by A1;

결과값( DECODE와 동일하게 데이터가 출력되는것을 볼 수 있다)

 

 

개인적으로는 평소에 사용하던 DECODE가 편했다. 

성능상으로 얼마나 차이날지는 모르겠다.

쿼리가 길어진다면

decode는 직관성이 떨어지겠지만

pivot은 pivot 바로 앞 select 에 필요한 쿼리를 넣어두어 사용하게되니 직관성은 올라갈것이라고 생각한다.

반응형