2012-06-06 31 views
32

Tengo una columna que tiene FirstName y LastName juntos. Estoy escribiendo un informe para separar el nombre y el apellido. ¿Cómo puedo separar FirstName y LastName en T-SQL?Subcadena T-SQL - separando nombre y apellido

+4

¿Puedes mostrar un ejemplo de datos? – raym0nd

+10

¿Siempre hay un espacio? ¿Qué pasa con 'Prince',' Alf' o 'Madonna'? ¿Qué tal 'Philip Seymour Hoffman' o' James van der Beek'? –

+6

Realmente, esta es una tarea ** muy ** difícil. Para hacerlo correctamente, necesitará un diccionario de nombres, o algo para comparar su entrada, y luego decidir cómo separarlos. Es una cosa realmente compleja de hacer – Lamak

Respuesta

2

Se podría hacer esto si nombre y primer apellido están separados por espacio:

SELECT SUBSTRING(FirstAndSurnameCol, 0, CHARINDEX(' ', FirstAndSurnameCol)) Firstname, 
SUBSTRING(FirstAndSurnameCol, CHARINDEX(' ', FirstAndSurnameCol)-1, LEN(FirstAndSurnameCol)) Surname FROM ... 
+0

SUBSTRING (FirstAndSurnameCol, CHARINDEX ('', FirstAndSurnameCol) +1, LEN (FirstAndSurnameCol)) –

12

esto debería funcionar:

Select 
    LTRIM(RTRIM(SUBSTRING(FullName, 0, CHARINDEX(' ', FullName)))) As FirstName 
, LTRIM(RTRIM(SUBSTRING(FullName, CHARINDEX(' ', FullName)+1, 8000)))As LastName 
FROM TABLE 

Editar: adoptado pista Jonny de Aaron y de la longitud fija de 8000 para evitar cálculos innecesarios.

+0

... y lo hace! –

+0

Si no hay espacio en el nombre original, esto dará como resultado que el primer nombre esté vacío y que el apellido sea el valor. – Evan

44

Suponiendo que el FirstName es todos los caracteres hasta el primer espacio:

SELECT 
    SUBSTRING(username, 1, CHARINDEX(' ', username) - 1) AS FirstName, 
    SUBSTRING(username, CHARINDEX(' ', username) + 1, 8000) AS LastName 
FROM 
    whereever 
+1

¿por qué usas un punto? – libjup

+1

y tal vez quiera usar LEN (nombre de usuario) en lugar de solo 8000 – libjup

+19

@libjup, hay una razón muy buena para usar un valor fijo que es más alto que cualquier longitud posible. ¿Por qué molestarse en calcular la longitud en cada fila? Ciclos perdidos. –

6
validate last name is blank 

SELECT 
person.fullName, 
(CASE WHEN 0 = CHARINDEX(' ', person.fullName) 
    then person.fullName 
    ELSE SUBSTRING(person.fullName, 1, CHARINDEX(' ', person.fullName)) end) as first_name, 
(CASE WHEN 0 = CHARINDEX(' ', person.fullName) 
    THEN '' 
    ELSE SUBSTRING(person.fullName,CHARINDEX(' ', person.fullName), LEN(person.fullName))end) last_name 

FROM person 
5

Esto se encargará de nombres como "Nombre Z. Apellido" y "Z Primero Último"

SELECT 
CASE 
    WHEN CHARINDEX(' ',name) = 0 THEN name 
    WHEN CHARINDEX(' ',name) = PATINDEX('% _[., ]%',name) THEN RTRIM(SUBSTRING(name, 1, CHARINDEX(' ',name) + 2)) 
    ELSE SUBSTRING(name,1, CHARINDEX(' ',name)) 
END [firstname] 
,CASE 
    WHEN CHARINDEX(' ',name) = 0 THEN '' 
    WHEN CHARINDEX(' ',name) = PATINDEX('% _[., ]%',name) THEN LTRIM(SUBSTRING(name, CHARINDEX(' ',name) + 3,1000)) 
    ELSE SUBSTRING(name,CHARINDEX(' ',name)+1,1000) 
END [lastname] 
FROM [myTable] 
15

La forma más sencilla que puedo encontrar para hacerlo es:

SELECT 
    SUBSTRING(FullName, 1, CHARINDEX(' ', FullName) - 1) AS FirstName, 
    REVERSE(SUBSTRING(REVERSE(FullName), 1, CHARINDEX(' ', REVERSE(FullName)) - 1)) AS LastName 
FROM 
    [PERSON_TABLE] 
+1

Prefiero esta solución, ya que elimina el segundo nombre del nombre completo –

+1

Esa es mi respuesta favorita también. Aunque, si desea que su FirstName contenga el (los) segundo (s) nombre (s) también (si tiene en cuenta que LastName es un nombre único), podría hacer algo como: 'REPLACE (FullName, REVERSE (SUBSTRING (REVERSE (FullName) , 1, CHARINDEX ('', REVERSE (FullName)) - 1)), '') AS FirstName' – TheWanderingMind

3

Aquí es una solución más elaborada con una función de SQL:

getFirstName

CREATE FUNCTION [dbo].[ufn_GetFirstName] 
( 
@FullName varchar(500) 
) 
RETURNS varchar(500) 
AS 
BEGIN 
-- Declare the return variable here 
DECLARE @RetName varchar(500) 

SET @FullName = replace(replace(replace(replace(@FullName, '.', ''), 'Mrs', ''), 'Ms', ''), 'Mr', '') 

SELECT 
    @RetName = 
    CASE WHEN charindex(' ', ltrim(rtrim(@FullName))) > 0 THEN left(ltrim(rtrim(@FullName)), charindex(' ', ltrim(rtrim(@FullName ))) - 1) ELSE '' END 

RETURN @RetName 
END 

getLastName

CREATE FUNCTION [dbo].[ufn_GetLastName] 
( 
@FullName varchar(500) 
) 
RETURNS varchar(500) 
AS 
BEGIN 
DECLARE @RetName varchar(500) 

IF(right(ltrim(rtrim(@FullName)), 2) <> ' I') 
BEGIN 
    set @RetName = left( 
    CASE WHEN 
    charindex(' ', reverse(ltrim(rtrim( 
    replace(replace(replace(replace(replace(replace(@FullName, ' Jr', ''), ' III', ''), ' II', ''), ' Jr.', ''), ' Sr', ''), 'Sr.', '') 
    )))) > 0 
    THEN 
    right(ltrim(rtrim( 
    replace(replace(replace(replace(replace(replace(@FullName, ' Jr', ''), ' III', ''), ' II', ''), ' Jr.', ''), ' Sr', ''), 'Sr.', '') 
    )) , charindex(' ', reverse(ltrim(rtrim( 
    replace(replace(replace(replace(replace(replace(@FullName, ' Jr', ''), ' III', ''), ' II', ''), ' Jr.', ''), ' Sr', ''), 'Sr.', '') 
    ))) ) - 1) 
    ELSE '' END 
    , 25) 
END 
ELSE 
BEGIN 
    SET @RetName = left( 
    CASE WHEN 
    charindex(' ', reverse(ltrim(rtrim( 
    replace(replace(replace(replace(replace(replace(replace(@FullName, ' Jr', ''), ' III', ''), ' II', ''), ' I', ''), ' Jr.', ''), ' Sr', ''), 'Sr.', '') 
    )))) > 0 
    THEN 
    right(ltrim(rtrim( 
    replace(replace(replace(replace(replace(replace(replace(@FullName, ' Jr', ''), ' III', ''), ' II', ''), ' I', ''), ' Jr.', ''), ' Sr', ''), 'Sr.', '') 
    )) , charindex(' ', reverse(ltrim(rtrim( 
    replace(replace(replace(replace(replace(replace(replace(@FullName, ' Jr', ''), ' III', ''), ' II', ''), ' I', ''), ' Jr.', ''), ' Sr', ''), 'Sr.', '') 
    ))) ) - 1) 
    ELSE '' END 
    , 25) 
END 

RETURN @RetName 
END 

USO:

SELECT dbo.ufn_GetFirstName(Fullname) as FirstName, dbo.ufn_GetLastName(Fullname) as LastName FROM #Names 
2

Usted puede tener problemas si el Fullname no contiene un espacio Suponiendo que la totalidad de NombreCompleto va a APELLIDOS si no hay espacio y FirstName se convierte en una cadena vacía, entonces usted puede utilizar esto:

SELECT 
    RTRIM(LEFT(FullName, CHARINDEX(' ', FullName))) AS FirstName, 
    SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, 8000) AS LastName 
FROM 
    MyNameTable; 
1

El siguiente código funciona con cadenas, primero el apellido M. Sustituya "Nombre" con el nombre de columna de su nombre. Como tiene un punto como personaje final cuando hay una inicial en el medio, debe reemplazar los 2 con 3 en cada una de las líneas (2, 6 y 8) y cambiar "DERECHA (Nombre, 1)" por "DERECHO". (Nombre, 2)" en la línea 8.

SELECT SUBSTRING(Name, 1, CHARINDEX(',', Name) - 1) LastName , 
CASE WHEN LEFT(RIGHT(Name, 2), 1) <> ' ' 
    THEN LTRIM(SUBSTRING(Name, CHARINDEX(',', Name) + 1, 99)) 
    ELSE LEFT(LTRIM(SUBSTRING(Name, CHARINDEX(',', Name) + 1, 99)), 
       LEN(LTRIM(SUBSTRING(Name, CHARINDEX(',', Name) + 1, 99))) 
       - 2) 
END FirstName , 
CASE WHEN LEFT(RIGHT(Name, 2), 1) = ' ' THEN RIGHT(Name, 1) 
    ELSE NULL 
END MiddleName 
2

creo que a continuación consulta será útil para dividir nombre y apellido de NombreCompleto incluso si sólo hay FirstName. Por ejemplo: 'Philip John' se puede dividir en Philip y John. Pero si solo hay Philip, debido a que charIndex of Space es 0, solo le dará ''.

Pruebe la de abajo.

declare @FullName varchar(100)='Philp John' 

Select 
    LTRIM(RTRIM(SUBSTRING(@FullName, 0, CHARINDEX(' ', @FullName+' ')))) As FirstName 
, LTRIM(RTRIM(SUBSTRING(@FullName, CHARINDEX(' ', @FullName+' ')+1, 8000)))As LastName 

Espero que esto te ayude.:)

Cuestiones relacionadas