Clique no banner para conhecer e adquirir o meu treinamento de Bancos de Dados no Azure

SQL Server – Utilizando a STRING_SPLIT para transformar strings de uma linha em colunas

Visualizações: 10.456 views
Esse post é a parte 5 de 5 da série String Split
Tempo de Leitura: 6 minutos

Fala pessoal!!
Nesse artigo eu gostaria de trazer um cenĂ¡rio que de vez em quando me perguntam sobre como resolver, que Ă© transformar strings de uma linha para colunas, muito utilizado para contas contĂ¡beis ou centro de custo, por exemplo, que foi exatamente a situaĂ§Ă£o que me pediram ajuda hĂ¡ uns 10 dias e resolvi tirar um tempinho para escrever esse artigo.

Exemplo de tabela:

E aĂ­ a pessoa precisava quebrar os nĂºmeros dos centros de custos (separados por “.”) em colunas diferentes, para conseguir montar uma hierarquia dos centros de custos e realizar algumas anĂ¡lises/montar relatĂ³rio em cima desses dados.

SoluĂ§Ă£o #1 – STRING_SPLIT

Caso vocĂª esteja utilizando a versĂ£o 2016+ do SQL Server, pode utiliar a funĂ§Ă£o STRING_SPLIT para atingir ao objetivo desejado:

Resultado:

Uma das grandes reclamações dos usuĂ¡rios sobre a funĂ§Ă£o STRING_SPLIT Ă© a falta de um campo numĂ©rico e incremental retornando o Ă­ndice de cada linha que foi quebrada. No exemplo acima, eu tive que criar essa linha utilizando uma funĂ§Ă£o de ranking (row_number), mas fique atento que isso NĂƒO garante a ordenaĂ§Ă£o correta.

Para converter essas vĂ¡rias linhas em colunas, podemos utilizar funções de agregaĂ§Ă£o com CASE’s, supondo que o nĂ­vel mĂ¡ximo seria de 10 nĂ­veis:

Resultado:

E caso vocĂª queira utilizar uma soluĂ§Ă£o mais dinĂ¢mica, onde o nĂºmero de nĂ­veis da tabela seja definido pelo nĂºmero de nĂ­veis dos dados reais, pode utilizar tambĂ©m o cĂ³digo abaixo:

Resultado:

SoluĂ§Ă£o #2 – fncSplitTexto

Caso vocĂª esteja utilizando uma versĂ£o anterior Ă  2016 do SQL Server, a funĂ§Ă£o STRING_SPLIT nĂ£o poderĂ¡ ser utilizada. Entretanto, vocĂª pode muito bem utilizar a funĂ§Ă£o fncSplitTexto, que disponibilizei no artigo Como quebrar um string em uma tabela de substrings utilizando um delimitador no SQL Server.

A vantagem do uso dessa funĂ§Ă£o, alĂ©m da retrocompatibilidade, Ă© que ela jĂ¡ possui o indexador por padrĂ£o.

Uma vez criada, a sua utilizaĂ§Ă£o Ă© quase idĂªntica ao uso da STRING_SPLIT:

Resultado:

E para ler os dados dinamicamente, de acordo com as colunas existentes nos dados, vocĂª pode utilizar o cĂ³digo abaixo:

Resultado:

A performance das duas funções

Se vocĂª jĂ¡ estudou um pouco a parte de Performance Tuning ou jĂ¡ leu o meu artigo SQL Server – ComparaĂ§Ă£o de performance entre Scalar Function e CLR Scalar Function, tenho certeza que vocĂª jĂ¡ sabe que a utilizaĂ§Ă£o da STRING_SPLIT Ă© bem mais rĂ¡pido que utilizar uma UDF (User Defined Function), mesmo que TVF (Table-valued Function).

Mesmo assim, vou mostrar a diferença de performance da funĂ§Ă£o nativa (vou testar com e sem o ROW_NUMBER) com uma funĂ§Ă£o UDF, num volume de dados de aproximadamente 20 mil registros:

Como vocĂªs puderam ver, a diferença de performance Ă© gigantesca entre uma UDF e uma funĂ§Ă£o nativa, e quanto mais dados na tabela, maior Ă© a diferença. Por este motivo, recomendo utilizar sempre a funĂ§Ă£o nativa STRING_SPLIT, quando possĂ­vel.

Bom pessoal, espero que vocĂªs tenham gostado desse artigo.
Um grande abraço e atĂ© o prĂ³ximo!