2012-09-12 3 views
2

je la chaîne suivante:Choisissez parmi 3 virgule dans la chaîne

bzip2,1,668,sometext,foo,bar 

Comment puis-je sélectionner uniquement sometext,foo,bar? La longueur de la chaîne précédant la 3ème virgule peut différer et il peut y avoir des virgules dans sometext,foo,bar. Je voudrais que ceci soit aussi concis que possible, c'est-à-dire de préférence 1 ligne de code, pas de boucle. Mais n'hésitez pas à poster toute solution que vous pensez.

+2

@a_horse_with_no_name Cela a absolument * zéro * à voir avec la question. –

+0

Peut-être que cela pourrait vous donner un début: http://stackoverflow.com/questions/8726111/sql-server-find-nth-occurrence-in-a-string – Bridge

+0

Y aura-t-il toujours exactement 3 virgules (4 "éléments") ? – Bridge

Répondre

0

Je viens de comprendre quelque chose qui fonctionne:

declare @v varchar(max) = 'bzip2,1,668,sometext' 
select substring(@v, CHARINDEX(',', @v, CHARINDEX(',', @v, CHARINDEX(',', @v)+1)+1)+1, len(@v)) 
+5

Je vous recommande d'accepter la réponse de @Joe alors, car c'est exactement la même solution qu'il a fournie il y a 3 minutes. –

+0

@Mike Oui, je l'ai compris un peu avant @Joe posté sa réponse. Son est légèrement différent cependant, il a plus de '1' et' @ v' –

+1

En règle générale, l'OP ne devrait pas poster des réponses à sa propre question dans les quelques minutes de l'affichage. –

6

essayez ceci:

Est-ce une sous-chaîne du 3 virgule à la fin de la chaîne .. Pour les 3 virgules, je suis en utilisant la fonction 3 fois

declare @str varchar(50)='bzip2,1,668,some,text' 

    select substring(@str, 
    CHARINDEX(',',@str,CHARINDEX(',',@str,CHARINDEX(',',@str,1)+1)+1)+1, 
    LEN(@str)-CHARINDEX(',',@str,CHARINDEX(',',@str,CHARINDEX(',',@str,1)+1)+1)) 

CHARINDEX() résultat :

some,text 
+0

Juste pour commenter ici, puisque je vois que cela continue d'être plus upvotes ... il utilise le double de la quantité de 'CHARINDEX's comme réponse.Une meilleure solution est: 'declare @v varchar (max) = 'bzip2,1,668, sometext' sélectionnez sous-chaîne (@v, CHARINDEX (',', @v, CHARINDEX (',', @v, CHARINDEX (', ', @v) +1) +1) +1, len (@v)) '(comme j'ai posté comme réponse). –

1

Voici une autre idée

DECLARE @xml AS XML,@str AS VARCHAR(50) 
    SET @str='bzip2,1,668,sometext,foo,bar' 

    SET @xml = CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML) 


     SELECT FinalResult = STUFF(@str,1,SUM(Length)+3,' ') FROM (SELECT 
           Rn = ROW_NUMBER() OVER(ORDER BY (SELECT 1)) 
           ,N.value('.', 'varchar(10)') as value 
           ,Length = LEN(N.value('.', 'varchar(10)')) 
          FROM @xml.nodes('X') as T(N))X 
     WHERE X.Rn<=3 

Résultat

sometext,foo,bar 
+1

L'ordre n'est pas garanti ici, ainsi vous pourriez potentiellement récupérer les éléments séparés de la chaîne dans un ordre différent lorsque le post-stuff contient des virgules. –

+0

Je le génère (numéro de ligne) d'une manière séquentielle.Alors comment l'ordre changera-t-il? –

+1

Peut-être pas, mais ce n'est pas le but, ce n'est pas garanti! Comment est-ce séquentiel? Votre ordre interne rend volontairement l'ordre arbitraire, et la requête externe n'utilise pas du tout l'ordre! –

2

code:

declare @input varchar(max) = 'bzip2,1,668,s,o,m,e,t,e,x,t,f,o,o,b,a,r' 
--declare @input varchar(max) = 'bzip2,,' 
declare @thirdCommaPosition int = nullif(charindex(',', @input, nullif(charindex(',', @input, nullif(charindex(',', @input, 1),0)+1),0)+1),0) 
select stuff(@input, 1, @thirdCommaPosition, '') 

Sortie:

s,o,m,e,t,e,x,t,f,o,o,b,a,r 

Modifier

Ajouté NULLIF de à la troisième partie de calcul de virgule, sans eux, il est possible d'obtenir des résultats incohérents.

Questions connexes