Concatenando dados em um único campo utilizando FOR XML PATH no SQL Server

Olá a todos!!!

Hoje gostaria de compartilhar um recurso do SQL Server que geralmente não é utilizado para o fim que apresento aqui, mas que foi muito interessante e útil pra mim: o recurso FOR XML PATH.

Este recurso é ótimo e bem útil para gerar consultas com resultados em XML (ajuda aqui), a perfomance da consulta também é muito boa, mas fui mais além e utilizei esse recurso para resolver um problema que estava me incomodando.

Imagine que você tem uma tabela A com relacionamento um para muitos com uma tabela B. Precisamos montar uma consulta onde em apenas uma linha apresentemos o resultado de todos os dados da tabela A e B.

Mas como fazer se o relacionamento é um para muitos ?

O Problema

Criar uma consulta que retorne os dados dos clientes e os motivos para cancelar a assinatura do serviço (cada cliente deve ser apresentado em uma linha só). Na tabela tbClientes, temos os dados dos clientes, e na tabela tbMotivosCancelamento, temos todos os motivos de cancelamento de cada cliente. (Para simplificar, neste exemplo não vou normalizar a tabela de motivos de cancelamento, vamos considerar que o texto com o motivo foi gravado diretamente na tabela tbMotivosCancelamento).

Modelo das Tabelas

Até descobrir este recurso estava utilizando uma function que para cada cliente retornava os motivos do cancelamento, mas na function era executada uma outra consulta, assim, para cada cliente uma consulta era executada, fazendo o custo da consulta ser muito alto.

O layout final da consulta deve ser algo do tipo:

Note que no resultado final, cada motivo é separado pelo caractere ‘-‘ e apresentado em um único campo, porém na tabela tbMotivosCancelamento cada motivo é gravado separadamente.

A solução

Utilizando o FOR XML PATH, neste caso teríamos o seguinte:

SELECT  Nome as ‘Nome do Cliente’, Cidade, UF, STUFF
                          ((SELECT     ‘ – [‘ + mc.MotivoCancelamento + ‘] ‘ AS [data()]
                              FROM         dbo.[tbMotivosCancelamento] mc
                              WHERE     c.Codigo = mc.CodCliente FOR XML PATH(”)),1,3,”) AS [Motivos do Cancelamento]
FROM         tbClientes c

That is it!!!!  Está feito…

O ganho de perfomance no meu caso foi de mais de 500% em relação à utilização da function.

Notem que utilizei o comando STUFF, ele serve apenas para eliminar o ‘-‘ do início do texto.

Até a próxima pessoal …

Anúncios

, , , , , , ,

  1. Deixe um comentário

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: