Extraire le premier mot d'une chaîne dans une requête SQL Server
Quelle est la meilleure façon d'extraire le premier mot d'une chaîne de requête de sql server?
8 réponses
SELECT CASE CHARINDEX(' ', @Foo, 1)
WHEN 0 THEN @Foo -- empty or single word
ELSE SUBSTRING(@Foo, 1, CHARINDEX(' ', @Foo, 1) - 1) -- multi-word
END
Vous pourriez peut-être l'utiliser dans un UDF:
CREATE FUNCTION [dbo].[FirstWord] (@value varchar(max))
RETURNS varchar(max)
AS
BEGIN
RETURN CASE CHARINDEX(' ', @value, 1)
WHEN 0 THEN @value
ELSE SUBSTRING(@value, 1, CHARINDEX(' ', @value, 1) - 1) END
END
GO -- test:
SELECT dbo.FirstWord(NULL)
SELECT dbo.FirstWord('')
SELECT dbo.FirstWord('abc')
SELECT dbo.FirstWord('abc def')
SELECT dbo.FirstWord('abc def ghi')
Je voulais faire quelque chose comme ça sans faire de fonction séparée, et j'ai trouvé cette approche simple d'une ligne:
DECLARE @test NVARCHAR(255)
SET @test = 'First Second'
SELECT SUBSTRING(@test,1,(CHARINDEX(' ',@test + ' ')-1))
Cela renverrait le résultat "First"
C'est court, mais pas aussi robuste, car il suppose que votre chaîne ne commence pas par un espace. Il traitera les entrées d'un mot, les entrées de plusieurs mots et les entrées de chaîne vide ou NULL.
Ajouter ce qui suit avant l'instruction RETURN
résoudrait les cas où un espace de début était inclus dans le champ:
SET @Value = LTRIM(RTRIM(@Value))
Amélioration de la réponse de Ben Brandt pour compenser même si la chaîne commence par l'espace en appliquant LTRIM (). Essayé d'éditer sa réponse mais rejeté, donc je l'affiche maintenant ici séparément.
DECLARE @test NVARCHAR(255)
SET @test = 'First Second'
SELECT SUBSTRING(LTRIM(@test),1,(CHARINDEX(' ',LTRIM(@test) + ' ')-1))
DECLARE @string NVARCHAR(50)
SET @string = 'CUT STRING'
SELECT LEFT(@string,(PATINDEX('% %',@string)))
La réponse de Marc m'a permis de trouver ce dont j'avais besoin, mais je devais utiliser patIndex
plutôt que charIndex
parce que parfois des caractères autres que des espaces marquent les extrémités des mots de mes données. Ici, j'utilise '%[ /-]%'
pour rechercher l'espace, la barre oblique ou le tiret.
Select race_id, race_description
, Case patIndex ('%[ /-]%', LTrim (race_description))
When 0 Then LTrim (race_description)
Else substring (LTrim (race_description), 1, patIndex ('%[ /-]%', LTrim (race_description)) - 1)
End race_abbreviation
from tbl_races
Résultats...
race_id race_description race_abbreviation
------- ------------------------- -----------------
1 White White
2 Black or African American Black
3 Hispanic/Latino Hispanic
Mise en garde: ceci est pour un petit ensemble de données (catégories de rapports de course fédéraux américains); Je ne sais pas ce qui arriverait à la performance lorsqu'elle serait mise à l'échelle à un nombre énorme.
A slight tweak to the function returns the next word from a start point in the entry CREATE FUNCTION [dbo].[GetWord] ( @value varchar(max) , @startLocation int ) RETURNS varchar(max) AS BEGIN SET @value = LTRIM(RTRIM(@Value)) SELECT @startLocation = CASE WHEN @startLocation > Len(@value) THEN LEN(@value) ELSE @startLocation END SELECT @value = CASE WHEN @startLocation > 1 THEN LTRIM(RTRIM(RIGHT(@value, LEN(@value) - @startLocation))) ELSE @value END RETURN CASE CHARINDEX(' ', @value, 1) WHEN 0 THEN @value ELSE SUBSTRING(@value, 1, CHARINDEX(' ', @value, 1) - 1) END END GO SELECT dbo.GetWord(NULL, 1) SELECT dbo.GetWord('', 1) SELECT dbo.GetWord('abc', 1) SELECT dbo.GetWord('abc def', 4) SELECT dbo.GetWord('abc def ghi', 20)
Essayez Ceci:
Select race_id, race_description
, Case patIndex ('%[ /-]%', LTrim (race_description))
When 0 Then LTrim (race_description)
Else substring (LTrim (race_description), 1, patIndex ('%[ /-]%', LTrim (race_description)) - 1)
End race_abbreviation
Depuis tbl_races