Lecture en boucle de valeurs supprimant 1 caractère à la fois

10

Je veux parcourir les valeurs et supprimer un caractère à la fois des valeurs et afficher le résultat.

Donc, si j'ai une table avec des valeurs:

ID
___
34679
13390
89906

Je veux que le résultat ressemble à ceci

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

Réponses:

19

Veuillez ne pas utiliser de boucles pour des choses comme ça (je réserverais également des CTE récursifs pour des scénarios où vous avez beaucoup moins de contrôle sur les choses, comme les hiérarchies). Les boucles sont mauvaises en SQL; SQL est optimisé pour fonctionner en ensembles.

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);

Résultats:

9
79
679
4679
0
90
390
3390
6
06
906
9906
Aaron Bertrand
la source
Merci pour votre aide. c'est exactement ce que j'essayais de réaliser.
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
la source
2
Pouvez-vous fournir des explications sur le fonctionnement de votre code? Cela aidera les futurs visiteurs.
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

RÉSULTAT:

4679 
679 
79 
9 
3390 
390 
90 
0 
9906 
906 
06 
6
Anish
la source
1
Alors, comment proposez-vous de faire cela, quand il y a beaucoup de lignes dans le tableau? Appelez la procédure - en boucle - pour chaque ligne? Vous avez maintenant besoin d'une requête pour extraire toutes ces valeurs, puis crée le code pour appeler la procédure stockée pour chacune. Vous avez donc une boucle pour chaque ligne du tableau qui appelle une procédure qui exécute elle-même une boucle pour chaque caractère dans chaque valeur. Ce n'est certainement pas un moyen efficace de résoudre ce problème.
Aaron Bertrand
Merci. Mais je suis d'accord avec Aaron. Ce n'est pas ce que je voulais. ma table a plus de 300k valeurs. donc cela ne fonctionnera pas.
Kashif Qureshi