Pivotando Dados no SQL – Parte 01

 

Resumo

 

Em muitas situações a modelagem das tabelas do sistema foi feita de tal maneira que, para enquadrar os dados nos formatos dos relatórios, é necessário transportar os dados que estão nas linhas para colunas e vice-versa. Este artigo mostra como transportar os dados através de exemplos que utilizam a instrução SELECT, para os casos onde a os dados a serem transportados já são conhecidos.

 

Introdução

 

Durante a modelagem das tabelas que vão armazenar os dados do sistema os analistas e programadores se preocupam principalmente com a normalização e o armazenamento dos dados e, na maioria das vezes, a geração de relatórios não é uma prioridade. O programador encarregado de criar a instrução SELECT que obtém os dados a partir das tabelas modeladas pode passar por dificuldades ao tentar enquadrá-los em alguns formatos de relatórios solicitados.

 

Uma das manipulações de dados mais comum é o transporte entre dados que estão em linhas para colunas e vice-versa. Este transporte é conhecido como pivotar dados, fazer referência cruzada ou rotacionar dados. O padrão SQL não sugere nenhuma opção específica para esta manipulação que geralmente fica sob a responsabilidade da interface da aplicação que apresenta os dados para o usuário.

 

Neste artigo vamos apresentar como executar algumas transformações em dados que estejam em linhas para colunas e vice-versa, com o objetivo de facilitar a geração de relatórios cujos formatos não são obtidos facilmente a partir do modelo de dados. Alguns exemplos práticos no SQL Server serão mostrados para facilitar o entendimento das idéias apresentadas.

 

Agrupando linhas em uma coluna

 

Em alguns casos onde joins são aplicados há a necessidade de transformar o resultado gerado por uma instrução SELECT, que utilizou joins, com o objetivo de agrupar dados de uma coluna e, junto com o agrupamento, aplicar uma concatenação dos valores de outras colunas.

 

Como exemplo, os dados da Tabela 1 foram obtidos através de uma instrução SELECT que utilizou joins para obter os dados de quais encomendas foram enviadas para quais estados. Os dados deste resultado foram armazenados em uma tabela chamada TB_ENCOMENDAS.


sql-25-07-2008pic01.JPG
Tabela 1. Dados sobre envio de encomendas.

 

Um relatório foi solicitado pedindo que as encomendas enviadas sejam agrupadas e que todos os estados para qual elas foram enviados sejam colocados na frente das encomendas, separados por vírgula. Para gerar este relatório devemos agrupar os dados por descrição da encomenda e juntar o nome dos estados. Infelizmente o padrão SQL e muitos outros bancos de dados não apresentam nenhuma função de agregação que concatena informações da maneira que necessitamos neste relatório.

 

Para resolver este problema, vamos criar uma função definida pelo usuário que será utilizada junto com a função de agregação MAX. Esta função vai receber como parâmetro a descrição da encomenda e retornar uma string com os estados, separados os estados por vírgula, para onde esta encomenda foi levada.

 

A Listagem 2 mostra a criação da função de usuário F_AGRUPA. A Tabela 2 mostra o resultado da instrução SELECT que utiliza a função F_AGRUPA e agrega os dados.


sql-25-07-2008pic02.JPG
Listagem 1. Função F_AGRUPA e instrução SELECT que agrupa os dados.


sql-25-07-2008pic03.JPG
Tabela 2. Relatório de encomendas.