web-dev-qa-db-fra.com

Comment extraire cette sous-chaîne spécifique dans SQL Server?

J'ai une chaîne avec un motif spécifique:

23;chair,red [$3]

c'est-à-dire un numéro suivi d'un point-virgule, puis un nom suivi d'un crochet gauche.

En supposant que le point-virgule ; existe toujours et que le crochet gauche [ existe toujours dans la chaîne, comment puis-je extraire le texte entre le ; et le [ dans une requête SQL Server? Merci.

11
RJIGO

Combinez les fonctions SUBSTRING(), LEFT() et CHARINDEX().

SELECT LEFT(SUBSTRING(YOUR_FIELD,
                      CHARINDEX(';', YOUR_FIELD) + 1, 100),
                      CHARINDEX('[', YOUR_FIELD) - 1)
FROM YOUR_TABLE;

Cela suppose que la longueur de votre champ ne dépassera jamais 100, mais vous pouvez le rendre plus intelligent pour en rendre compte si nécessaire en utilisant la fonction LEN(). Je n'ai pas pris la peine, car il y a déjà suffisamment de choses là-dedans et je n'ai pas d'instance contre laquelle tester, alors je regarde juste entre parenthèses, etc.

20
Marc

En supposant qu'ils existent toujours et ne font pas partie de vos données, cela fonctionnera:

declare @string varchar(8000) = '23;chair,red [$3]'
select substring(@string, charindex(';', @string) + 1, charindex(' [', @string) - charindex(';', @string) - 1)
5
Michael Dean

Une alternative à la réponse fournie par @Marc

SELECT SUBSTRING(LEFT(YOUR_FIELD, CHARINDEX('[', YOUR_FIELD) - 1), CHARINDEX(';', YOUR_FIELD) + 1, 100)
FROM YOUR_TABLE
WHERE CHARINDEX('[', YOUR_FIELD) > 0 AND
    CHARINDEX(';', YOUR_FIELD) > 0;

Cela permet de s’assurer que les délimiteurs existent et de résoudre le problème de la réponse actuellement acceptée: effectuer la dernière opération GAUCHE consiste à utiliser la position du dernier délimiteur dans la chaîne originale plutôt que la sous-chaîne révisée.

1
Reuben

Si vous avez besoin de scinder quelque chose en 3, comme une adresse électronique et que vous ne connaissez pas la longueur de la partie centrale, essayez ceci (je viens de lancer ceci sur sqlserver 2012 pour que je sache que cela fonctionne):

SELECT top 2000 
    emailaddr_ as email,
    SUBSTRING(emailaddr_, 1,CHARINDEX('@',emailaddr_) -1) as username,
    SUBSTRING(emailaddr_, CHARINDEX('@',emailaddr_)+1, (LEN(emailaddr_) - charindex('@',emailaddr_) - charindex('.',reverse(emailaddr_)) ))  domain 
FROM 
    emailTable
WHERE 
    charindex('@',emailaddr_)>0 
    AND 
    charindex('.',emailaddr_)>0;
GO

J'espère que cela t'aides.

0
TekOps

sélectionnez une sous-chaîne (your_field, CHARINDEX (';', your_field) +1 , CHARINDEX ('[', your_field) -CHARINDEX (';', your_field) -1) à partir de your_table

Je ne peux pas amener les autres à travailler. Je crois que vous voulez juste ce qui est entre les deux; et '[' dans tous les cas, quelle que soit la longueur de la chaîne entre les deux. Après avoir spécifié le champ dans la fonction de sous-chaîne, le deuxième argument est l'emplacement de départ de ce que vous allez extraire. C'est là où le ';' est + 1 (quatrième position - le c), car vous ne voulez pas inclure ';'. L'argument suivant prend l'emplacement du '[' (position 14) et soustrait l'emplacement du spot après le ';' (quatrième position - c’est la raison pour laquelle je soustrais maintenant 1 dans la requête). En gros, cela indique une sous-chaîne (champ, emplacement où je souhaite que la sous-chaîne commence, combien de temps je souhaite une sous-chaîne). J'ai utilisé cette même fonction dans d'autres cas. Si certains champs n'ont pas ';' et '[', vous voudrez les filtrer dans la clause "où", mais c'est un peu différent de la question. Si ton ';' was say ... ';;;', vous utiliseriez 3 au lieu de 1 dans l'exemple. J'espère que cela t'aides! 

0
Nate Lincoln