Utilizando o select para formatar dados em relatórios – Parte 02

 

Resumo

 

Alguns relatórios gerados a partir de instruções SELECT permitem a apresentação dos dados para os usuários na forma de lista, onde os valores das colunas são colocados linha a linha. Em determinadas situações a quantidade dos dados precisa ser divida em colunas com o objetivo de facilitar a leitura do relatório. Este artigo apresenta uma maneira de dividir os dados entre as colunas apresentando-os alternadamente.

 

Dividindo os dados

 

Uma duplicação dos dados como a que foi apresentada não faz muito sentido. Dividiremos os dados colocando-os lado a lado nas colunas semelhantes, isto é, na primeira linha colocaremos o valor 1 para a coluna ID, ‘A’ para Nome e 16/09/2005 para a coluna Data. Na mesma linha vamos colocar o valor 2 para a coluna ID1, ‘B’ para NOME1 e 15/09/2005 para a coluna DATA1.

 

Com os dados neste novo formato gastaríamos apenas duas linhas no relatório ao invés de quatro para mostrar todos os dados. O leitor do relatório seguiria uma linha horizontal imaginária durante a leitura, facilitando o entendimento dos dados. A Tabela 3 apresenta os dados no formato desejado, considerando apenas as quatro linhas da tabela TB_SEPARA.


sql-17-07-2008pic01.JPG
Tabela 3. Desejável divisão dos dados através das colunas.

 

Para aplicar esta divisão dos dados e colocá-los neste formato devemos partir de um caso particular primeiro, ou seja, consideraremos que a tabela tem uma quantidade par de registros. Depois trataremos do caso onde a quantidade de registros da tabela é ímpar.

 

A idéia utilizada para colocar nos dados neste formato é pensar em dividir os dados e depois relacioná-los. Analisando os dados da ‘primeira tabela’, aquela que manipulamos através do alias A, podemos perceber que os ID’s são ímpares. Computacionalmente falando, o resto da divisão por dois de cada um dos ID’s do alias A deve ser igual 1. De forma análoga, os ID’s do alias B devem ser pares, ou seja, o resto da divisão por dois destes ID’s deve ser zero. A aplicação do operador módulo (%) nos permite efetuar esta divisão e obter somente as linhas cujos ID’s são pares, para o alias A, e as linhas cujos ID’s são ímpares, para o alias B.

 

Até aqui planejamos como iremos separar os dados entre os alias, que serão implementados através de sub-querys na nossa instrução SELECT. Se executarmos a instrução apresentada na Listagem 2:

 

sql-17-07-2008pic03.JPG 

Listagem 2. Instrução SELECT que divide os dados entre os dois alias.

 

Não vamos obter o que desejamos. O problema da instrução apresentada na Listagem 2 é que o SQL Server, assim como muitos bancos de dados, faz um cross join com os dados das tabelas utilizadas na instrução SELECT quando não aplicamos uma regra de join entre as tabelas da instrução. O que precisamos fazer agora é implementar uma regra de join que relacione corretamente os dados dois alias A e B.

 

Analisando os dados das colunas ID e ID1 na Tabela 3 podemos perceber que o valor da coluna ID1 é sempre o valor da coluna ID mais um. Esta será a nossa regra do join, que pode ser vista na instrução SELECT da Listagem 3. Na cláusula WHERE utilizamos a coluna ID para o alias B, pois é somente na lista de colunas da instrução que trocamos o nome da coluna para ID1.

 

sql-17-07-2008pic04.JPG 

Listagem 3. Instrução SELECT com o critério de join.

 

No SQL Server temos duas maneiras de fazer joins: podemos utilizar a cláusula INNER JOIN ou fazer o join como na instrução da Listagem 3, relacionando as colunas na cláusula WHERE. Qualquer uma das duas maneiras pode ser utilizada, pois elas não influenciam no resultado final que a instrução gera.

 

Executando a instrução SELECT da Listagem 3 obteremos os dados da maneira que desejamos e que foram mostrados na Tabela 3. E para o caso onde o número de linhas da tabela é ímpar ?

Neste caso é preciso definir como a linha ‘a mais’ será mostrada. Uma maneira adequada é mostrar esta linha ‘a mais’ é inseri-la no primeiro conjunto de linhas (colunas do alias A) e deixar as colunas correspondentes do segundo conjunto de linhas (colunas do alias B) com o valor NULL, que pode ser trocado na aplicação que apresenta os dados ou através do uso da estrutura CASE do SQL Server.

 

A modificação necessária na instrução SELECT é simples: basta utilizar um LEFT OUTTER JOIN, ou seja, indicar na instrução SELECT que as linhas do alias A que não se relacionarem com as linhas do alias B também devem ser incluídas no resultado. A instrução final é apresentada na Listagem 4.

 

sql-17-07-2008pic05.JPG
Listagem 4.
Instrução SELECT que utiliza um LEFT OUTTER JOIN.

 

Notem que o operador *= foi implementado para indicar o LEFT OUTTER JOIN, que pode ser trocado sem problemas pela outra maneira de se fazer left joins no SQL Server. Supondo que a tabela TB_SEPARA tenha cinco linhas, a instrução SELECT da Listagem 4 irá transformar os dados para o formato exibido na Tabela 4.


sql-17-07-2008pic02.JPG 
Tabela 4.
Divisão da quantidade ímpar de dados.

 

Conclusão

 

Este artigo apresentou uma implementação que duplica os dados de uma tabela através da criação de novas colunas e da separação dos dados, desde que haja uma coluna na tabela que apresente uma numeração seqüencial sem falhas. Algumas instruções SELECT foram apresentadas para implementar esta divisão utilizando o dialeto T-SQL, que pode ser facilmente convertido para outros dialetos do SQL. Outras maneiras de dividir os dados podem ser implementadas, com a divisão dos dados entre colunas, mas isso é assunto para um próximo artigo.