DATA 전문가로 가는 길

[SQL] Oracle Pivot 함수를 사용한 동적 항목, 값 처리 본문

Data Architecture/SQL Query

[SQL] Oracle Pivot 함수를 사용한 동적 항목, 값 처리

EstenPark 2015. 11. 18. 15:22

금융 데이터를 가공할 때 결산년월을 선택하여 해당 년도의 계정 과목을 보여주고, 값이 얼마인지 출력하기도 합니다. 


이번에는 기본적인 메타 관리를 원칙으로 데이터 항목, 데이터 값을 동적으로 처리하는 쿼리입니다. 가변적 컬럼을 pivot 함수 for in절에 넣을 수 있으면 좋지만, PL/SQL을 활용하지 않는 한 어려움이 있어서 원하는 결과를 위에서 받고, 아래서는 최종 결과를 리턴하는 방식으로 쿼리를 작성 하였습니다.


[테이블 메타 관리 ERD]


[테이블 생성]


[데이터 생성]


[쿼리]


/*
  1. 테이블 기준으로 컬럼의 ID와 항목을 가져온다.
*/
SELECT    A.TB_UNIQ_NO /* 테이블고유번호 */
         ,A.TB_ID      /* 테이블아이디   */
         ,LISTAGG(B.COLUMN_POS_NO, ',') WITHIN GROUP (ORDER BY B.COLUMN_POS_NO) AS COLUMN_POS_NO_PATH
         ,LISTAGG(B.COLUMN_ID, ',')     WITHIN GROUP (ORDER BY B.COLUMN_POS_NO) AS COLUMN_ID_PATH
FROM      ESP_TB_INFO A 
         ,ESP_TB_COLUNM B  
WHERE     A.TB_ID = 'ESP_USER_INFO' /* [조건] 테이블ID */
AND       A.OWNER = 'ESTENPARK'     /* [조건] 테이블 소유자 */
AND       B.TB_UNIQ_NO = A.TB_UNIQ_NO
GROUP BY  A.TB_UNIQ_NO, A.TB_ID
;


/*
  2. 컬럼의 항목과 값을 모두 한번에 출력한다.
*/
SELECT    XX.*
FROM      (SELECT    X.*
           FROM      (SELECT    A.COLUMN_ID, A.COLUMN_POS_NO, 'No.' AS ROW_NO
                      FROM      ESP_TB_COLUNM A
                      WHERE     A.TB_UNIQ_NO = 1) 
           PIVOT     (MAX(COLUMN_ID) 
                        FOR COLUMN_POS_NO IN (1, 2, 3) /* [조건] COLUMN_POS_NO_PATH 컬럼의 값 */
                     ) X
           UNION ALL
           SELECT    X.*
           FROM      (SELECT    A.COLUMN_ID, TO_CHAR(A.ROW_NO) ROW_NO, A.COLUMN_VAL
                      FROM      ESP_TB_COLUMN_VAL A
                      WHERE     A.TB_UNIQ_NO = 1) 
           PIVOT    (MAX(COLUMN_VAL) 
                       FOR COLUMN_ID IN ('USER_ID', 'USER_NM', 'USER_GRP_NO') /* [조건] COLUMN_ID_PATH 컬럼의 값 */
           ) X
) XX
ORDER BY  DECODE(XX.ROW_NO, 'No.', '0', XX.ROW_NO)    


기본적으로 원하는 소유자와 테이블ID를 조건절에 대입 시켜서 유일한 값(Unique Index)을 가질 수 있습니다. 그 상태로 아래 쿼리에 [조건]에 대입을 하게 된다면 항목 순서와 일치하게 결과를 볼 수 있습니다.


[쿼리 최종 결과]



Comments