quarta-feira, 18 de setembro de 2013

Fazendo Pivoteamento no Oracle 11g


Inúmeras vezes precisei fazer o pivoteamento ou transposição de dados e sempre usei aquela velha estratégia de MAX com DECODE e GROUP BY. Porem isso deixava uma limitação na quantidade de campos que que precisava pivotear. Com a função PIVOT do Oracle 11g isso simplificou muito.

Vamos supor que tenhamos a query abaixo, onde o nome da tabela pode ser variável

SELECT column_name

FROM SYS.all_tab_columns
WHERE OWNER = 'SCOTT'
AND TABLE_NAME = 'EMP';

Para transformar as linhas com o nome das colunas em uma lista separada por virgula, fiz isso:


SELECT replace(

            replace(
                    replace (column_name_xml,'<PivotSet><item><column name = "COLUMN_NAME">'),
                    '</column><column name = "ERR">1</column></item><item><column name = "COLUMN_NAME">',','),
              '</column><column name = "ERR">1</column></item></PivotSet>') as LISTA_COLUNAS
FROM (SELECT column_name
        FROM SYS.all_tab_columns
          WHERE OWNER = 'SCOTT'
          AND table_name = 'EMP')
PIVOT XML (count(1) AS err FOR (column_name) IN (SELECT column_name
                                                FROM SYS.all_tab_columns
                                                  WHERE OWNER = 'SCOTT'
                                                  AND table_name = 'EMP'));
                                                                                                                                                                                             
Precisei usar PIVOT XML pois a função PIVOT não aceita uma subquery, apenas uma listagem.