Extraer la primera palabra de una cadena en una consulta de SQL Server


¿Cuál es la mejor manera de extraer la primera palabra de una cadena en una consulta de sql server?

 31
Author: holiveira, 2009-04-02

8 answers

SELECT CASE CHARINDEX(' ', @Foo, 1)
     WHEN 0 THEN @Foo -- empty or single word
     ELSE SUBSTRING(@Foo, 1, CHARINDEX(' ', @Foo, 1) - 1) -- multi-word
END

Quizás podrías usar esto en 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')
 59
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-01 22:43:00

Quería hacer algo como esto sin hacer una función separada, y se me ocurrió este simple enfoque de una línea:

DECLARE @test NVARCHAR(255)
SET @test = 'First Second'

SELECT SUBSTRING(@test,1,(CHARINDEX(' ',@test + ' ')-1))

Esto devolvería el resultado "Primero"

Es corto, pero no tan robusto, ya que asume que tu cadena no comienza con un espacio. Manejará entradas de una palabra, entradas de varias palabras y entradas de cadena vacía o NULA.

 29
Author: Ben Brandt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-13 17:11:02

Agregar lo siguiente antes de la instrucción RETURN resolvería los casos en los que se incluyó un espacio inicial en el campo:

SET @Value = LTRIM(RTRIM(@Value))
 5
Author: Ryan Pratt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-14 11:36:33

Mejora de la respuesta de Ben Brandt para compensar incluso si la cadena comienza con espacio aplicando LTRIM(). Intenté editar su respuesta pero la rechacé, así que ahora la estoy publicando aquí por separado.

DECLARE @test NVARCHAR(255)
SET @test = 'First Second'

SELECT SUBSTRING(LTRIM(@test),1,(CHARINDEX(' ',LTRIM(@test) + ' ')-1))
 3
Author: ricsierics,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-04 09:31:08
DECLARE @string NVARCHAR(50)

SET @string = 'CUT STRING'

SELECT LEFT(@string,(PATINDEX('% %',@string)))
 2
Author: Vikram Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-03 11:25:24

La respuesta de Marc me llevó la mayor parte del camino a lo que necesitaba, pero tuve que ir con patIndex en lugar de charIndex porque a veces los caracteres que no son espacios marcan los extremos de las palabras de mis datos. Aquí estoy usando '%[ /-]%' para buscar espacio, barra o guión.

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

Resultados...

race_id  race_description           race_abbreviation
-------  -------------------------  -----------------
1        White                      White
2        Black or African American  Black
3        Hispanic/Latino            Hispanic

Advertencia: esto es para un pequeño conjunto de datos (categorías de informes federales de carrera de EE.UU.); No se qué pasaría con el rendimiento cuando se escalara a números enormes.

 1
Author: Steve L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-26 14:01:48
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) 

 0
Author: Edward Thompson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-14 06:05:20

Prueba Esto:

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

De tbl_races

 0
Author: vinay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-02 02:08:01