Loop através de valores eliminando 1 caractere de cada vez

10

Eu quero percorrer os valores e retirar um caractere de cada vez dos valores e exibir o resultado.

Então, se eu tenho uma tabela com valores:

ID
___
34679
13390
89906

Eu quero que o resultado fique assim

Id
----
4679
679
79
9
3390
390
90
0
9906
906
06
6
Kashif Qureshi
fonte

Respostas:

19

Por favor, não use loops para coisas como essa (eu também reservaria CTEs recursivas para cenários em que você tem muito menos controle sobre coisas, como hierarquias). Loops são ruins no SQL; SQL é otimizado para trabalhar em conjuntos.

DECLARE @foo TABLE(ID INT);

INSERT @foo VALUES(34679),(13390),(89906);

;WITH x AS 
(
  SELECT TOP (2048) n = ROW_NUMBER() OVER (ORDER BY Number)
  FROM master.dbo.spt_values ORDER BY Number
)
SELECT RIGHT(f.ID, x.n) FROM x
INNER JOIN @foo AS f
ON x.n < LEN(f.ID);

Resultados:

9
79
679
4679
0
90
390
3390
6
06
906
9906
Aaron Bertrand
fonte
Obrigado pela sua ajuda. isto é exatamente o que eu estava tentando alcançar.
Kashif Qureshi
-1
declare @MyString varchar(500)

set MyString = '1,2.3#45.#,.6'

select dbo.RemoveChars(MyString, '#,.')

create function [dbo].[RemoveChars] (
    @InputString varchar(MAX)
    ,@CharsToRemove varchar(500)
    )
returns varchar(MAX)
as
begin
    declare @len int
        ,@Counter int
        ,@OneChar char(1)

    set @Counter = 1
    set @len = LEN(@CharsToRemove);

    while (1 = 1)
    begin
        set @OneChar = SUBSTRING(@CharsToRemove, @Counter, 1)
        set @InputString = REPLACE(@InputString, @OneChar, '')
        set @Counter = @Counter + 1

        if (
                @Counter > @len
                or @Counter > 20
                )
            break;
    end

    return @InputString
end
Eyad
fonte
2
Você pode fornecer uma explicação sobre como seu código funciona? Isso ajudará futuros visitantes.
Kin Shah
-3
CREATE PROC udploop (@num varchar(10))
AS
       BEGIN 
             DECLARE @len int; 
             SET @len = LEN(@num); 
             WHILE (@len > 1)
                   BEGIN    
                         SELECT
                            @num = RIGHT(@num, @len - 1); 
                         PRINT @num;
                         SET @len = LEN(@num);
                   END 
       END

EXEC:

EXEC udploop 34679 
EXEC udploop 13390 
EXEC udploop 89906

RESULTADO:

4679 
679 
79 
9 
3390 
390 
90 
0 
9906 
906 
06 
6
Anish
fonte
11
Então, como você propõe isso, quando há muitas linhas na tabela? Chamar o procedimento - em um loop - para cada linha? Agora você precisa de uma consulta para extrair todos esses valores e, em seguida, cria o código para chamar o procedimento armazenado para cada um. Portanto, você tem um loop para cada linha da tabela que chama um procedimento que executa um loop para cada caractere em cada valor. Definitivamente, essa não é uma maneira eficiente de resolver esse problema.
Aaron Bertrand
obrigado. Mas, eu concordo com Aaron. Não era isso que eu queria. minha tabela tem mais de 300k valores. então isso não vai funcionar.
Kashif Qureshi