TransWikia.com

Remover números anterior a vírgula

Stack Overflow em Português Asked by Enio Amarantes on November 7, 2021

Tenho uma sequência numérica em string tipo '0,1;2,2;5,3;8,4;'.

Preciso que o resultado saia '1,2,3,4' apenas os números após a virgula.

Já tentei a seguinte consulta:

{select replace(replace('0,1;2,2;5,3;8,4;', '[0-9'],', ''), ';', ',')}

Porém não substitui nada. Como faço para usar o operador que identifica qualquer numeral?

One Answer

A solução que vou propor necessita que cada linha possua uma identificação única. Assim, para fins de demonstração da solução será considerada que essa identificação única existe.

-- código #1
CREATE TABLE tabela (ID_sequencia tinyint identity, Sequencia varchar(100));
INSERT into tabela values ('0,10;2,2;5,13;8,4');
go

Para separar os elementos será utilizada a função de usuário DelimitedSplit8K, de autoria de Jeff Moden. Informações sobre esta função estão disponíveis no artigo An Improved SQL 8K “CSV Splitter” Function, sendo que o código fonte dela também pode ser obtido no artigo Separar em partes uma lista de valores.

O primeiro passo é separar cada par:

-- código #2
SELECT ID_sequencia, T.sequencia, S1.ItemNumber as seqPar, S1.Item as Par
  from tabela as T 
       cross apply dbo.DelimitedSplit8K (T.sequencia, ';') as S1;

Após separar cada par, deve-se obter cada elemento de cada par:

-- código #3
with
gPar as (
SELECT ID_sequencia, T.sequencia, S1.ItemNumber as seqPar, S1.Item as Par
  from tabela as T 
       cross apply dbo.DelimitedSplit8K (T.sequencia, ';') as S1
),
gElemento as (
SELECT P.ID_Sequencia, P.sequencia, P.seqPar, 
       S2.ItemNumber as seqElemento, S2.Item as Elemento
  from gPar as P
       cross apply dbo.DelimitedSplit8K (P.Par, ',') as S2
)
SELECT ID_Sequencia, sequencia, seqPar, seqElemento, Elemento
  from gElemento 
  order by ID_Sequencia, seqPar;

Tendo-se cada elemento separado, o passo final é agrupar os elementos finais de cada par, na ordem de cada par. Eis o código SQL completo, utilizando a função STRING_AGG para agrupar os elementos:

-- código #4
-- Autor: José Diz 
with
gPar as (
SELECT ID_sequencia, T.sequencia, S1.ItemNumber as seqPar, S1.Item as Par
  from tabela as T 
       cross apply dbo.DelimitedSplit8K (T.sequencia, ';') as S1
),
gElemento as (
SELECT P.ID_Sequencia, P.sequencia, P.seqPar, 
       S2.ItemNumber as seqElemento, S2.Item as Elemento
  from gPar as P
       cross apply dbo.DelimitedSplit8K (P.Par, ',') as S2
)
SELECT ID_Sequencia, 
       string_agg (Elemento, ',') within group (order by seqPar)
  from gElemento
  where seqElemento = 2
  group by ID_Sequencia;

Como a função STRING_AGG somente funciona a partir da versão 2017 do SQL Server, ela pode ser substituída pela técnica blackbox xml nas versões anteriores do SQL Server. Detalhes no artigo Concatenação de várias linhas de uma mesma coluna.

-- código #5 v2
-- Autor: José Diz 
with
gPar as (
SELECT ID_sequencia, T.sequencia, S1.ItemNumber as seqPar, S1.Item as Par
  from tabela as T 
       cross apply dbo.DelimitedSplit8K (T.sequencia, ';') as S1
),
gElemento as (
SELECT P.ID_Sequencia, P.sequencia, P.seqPar, 
       S2.ItemNumber as seqElemento, S2.Item as Elemento
  from gPar as P
       cross apply dbo.DelimitedSplit8K (P.Par, ',') as S2
)
SELECT E.ID_Sequencia, 
       --string_agg (Elemento, ',') within group (order by seqPar)
       stuff ((SELECT ',' + T.Elemento
                 from gElemento as T
                 where T.ID_Sequencia = E.ID_Sequencia
                       and T.seqElemento = 2
                 order by T.seqPar
                 for xml path(''), TYPE).value('.', 'varchar(max)'),
              1, 1, '') as novaSequencia       
  from gElemento as E
  where E.seqElemento = 2
  group by E.ID_Sequencia;

Answered by José Diz on November 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP