E aí pessoal, tudo belezinha com vocês? Segue um post rápido, só para registrar um assunto que rolou em um grupo de discussão do Telegram há algum tempo atrás e só agora eu resolvi parar para escrever a respeito…
Pense no seguinte cenário:
Eu tenho uma tabela onde uma das colunas é um campo texto (varchar(XXX)), separado por ‘;’ (ou qualquer outro caractere de sua preferência).
Mas porque eu teria isso? Bom, imagine que você crie uma trigger para a fazer sua auditoria e, ao invés de guardar em colunas, você guarda em um varchar as alterações…
O objetivo: Agora mudaram de ideia e precisam fazer com que esse texto retorne como colunas em uma query.
Algo assim:
Algumas observações:
- Vou trabalhar com uma quantidade fixa de colunas (supor que o máximo é 6), mas é totalmente possível investigar quantas colunas tem no maior texto, para criar a tabela.
- Se houver um campo vazio (;;), devo deixar o campo como NULL
Vamos lá…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
-- Criando uma CTE, apenas para não criar nenhum objeto físico no banco. ;with cte_val as ( select * from (values (1,'a;b;;c;d;e'),(2,'x;;y;;z'),(3,'t;u;y;t;d;a'),(4,'a;b;c') ) as MinhaTabelaDeOrigem(Codigo, Texto) ) select Codigo, [col1], [col2], [col3], [col4], [col5], [col6] from ( select Codigo, NULLIF(value,'') AS value, -- Se eu não fizer essa validação a função STRING_SPLIT vai retornar a linhas como vazias - e não como nulas, que é o que eu preciso concat('col',ROW_NUMBER() over (PARTITION BY Codigo order by Codigo )) AS LINHA from cte_val cross apply STRING_SPLIT(Texto,';') as t ) z pivot (max(value) FOR LINHA in ([col1], [col2], [col3], [col4], [col5], [col6])) as pvt |
Simples, não? 🙂
Lembrete importante: Devido ao uso do STRING_SPLIT, essa consulta só vai rodar acima do SQL Server 2016.
Valeu pessoal! Bons estudos!