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