Si te encuentras con algo que no comprendes puedes dejarlo en la sección de comentarios y te ayudaremos lo más rápido posible.
Solución:
Aquí hay un ejemplo independiente, con datos de prueba fácilmente manipulables.
Con este ejemplo, si tiene un nombre con más de tres partes, todas las cosas “extra” se colocarán en el campo LAST_NAME. Se hace una excepción para cadenas específicas que se identifican como “títulos”, como “DR”, “MRS” y “MR”.
Si falta el segundo nombre, solo obtendrá FIRST_NAME y LAST_NAME (MIDDLE_NAME será NULL).
Podría convertirlo en una gota gigante anidada de SUBSTRING, pero la legibilidad es lo suficientemente difícil como lo es cuando hace esto en SQL.
Editar: manejar los siguientes casos especiales:
1 – El campo NOMBRE es NULL
2 – El campo NOMBRE contiene espacios iniciales/posteriores
3 – El campo NOMBRE tiene > 1 espacio consecutivo dentro del nombre
4 – El campo NOMBRE contiene SOLO el primer nombre
5 – Incluya el nombre completo original en el resultado final como una columna separada, para facilitar la lectura
6 – Manejar una lista específica de prefijos como una columna de “título” separada
SELECT
FIRST_NAME.ORIGINAL_INPUT_DATA
,FIRST_NAME.TITLE
,FIRST_NAME.FIRST_NAME
,CASE WHEN 0 = CHARINDEX(' ',FIRST_NAME.REST_OF_NAME)
THEN NULL --no more spaces? assume rest is the last name
ELSE SUBSTRING(
FIRST_NAME.REST_OF_NAME
,1
,CHARINDEX(' ',FIRST_NAME.REST_OF_NAME)-1
)
END AS MIDDLE_NAME
,SUBSTRING(
FIRST_NAME.REST_OF_NAME
,1 + CHARINDEX(' ',FIRST_NAME.REST_OF_NAME)
,LEN(FIRST_NAME.REST_OF_NAME)
) AS LAST_NAME
FROM
(
SELECT
TITLE.TITLE
,CASE WHEN 0 = CHARINDEX(' ',TITLE.REST_OF_NAME)
THEN TITLE.REST_OF_NAME --No space? return the whole thing
ELSE SUBSTRING(
TITLE.REST_OF_NAME
,1
,CHARINDEX(' ',TITLE.REST_OF_NAME)-1
)
END AS FIRST_NAME
,CASE WHEN 0 = CHARINDEX(' ',TITLE.REST_OF_NAME)
THEN NULL --no spaces @ all? then 1st name is all we have
ELSE SUBSTRING(
TITLE.REST_OF_NAME
,CHARINDEX(' ',TITLE.REST_OF_NAME)+1
,LEN(TITLE.REST_OF_NAME)
)
END AS REST_OF_NAME
,TITLE.ORIGINAL_INPUT_DATA
FROM
(
SELECT
--if the first three characters are in this list,
--then pull it as a "title". otherwise return NULL for title.
CASE WHEN SUBSTRING(TEST_DATA.FULL_NAME,1,3) IN ('MR ','MS ','DR ','MRS')
THEN LTRIM(RTRIM(SUBSTRING(TEST_DATA.FULL_NAME,1,3)))
ELSE NULL
END AS TITLE
--if you change the list, don't forget to change it here, too.
--so much for the DRY prinicple...
,CASE WHEN SUBSTRING(TEST_DATA.FULL_NAME,1,3) IN ('MR ','MS ','DR ','MRS')
THEN LTRIM(RTRIM(SUBSTRING(TEST_DATA.FULL_NAME,4,LEN(TEST_DATA.FULL_NAME))))
ELSE LTRIM(RTRIM(TEST_DATA.FULL_NAME))
END AS REST_OF_NAME
,TEST_DATA.ORIGINAL_INPUT_DATA
FROM
(
SELECT
--trim leading & trailing spaces before trying to process
--disallow extra spaces *within* the name
REPLACE(REPLACE(LTRIM(RTRIM(FULL_NAME)),' ',' '),' ',' ') AS FULL_NAME
,FULL_NAME AS ORIGINAL_INPUT_DATA
FROM
(
--if you use this, then replace the following
--block with your actual table
SELECT 'GEORGE W BUSH' AS FULL_NAME
UNION SELECT 'SUSAN B ANTHONY' AS FULL_NAME
UNION SELECT 'ALEXANDER HAMILTON' AS FULL_NAME
UNION SELECT 'OSAMA BIN LADEN JR' AS FULL_NAME
UNION SELECT 'MARTIN J VAN BUREN SENIOR III' AS FULL_NAME
UNION SELECT 'TOMMY' AS FULL_NAME
UNION SELECT 'BILLY' AS FULL_NAME
UNION SELECT NULL AS FULL_NAME
UNION SELECT ' ' AS FULL_NAME
UNION SELECT ' JOHN JACOB SMITH' AS FULL_NAME
UNION SELECT ' DR SANJAY GUPTA' AS FULL_NAME
UNION SELECT 'DR JOHN S HOPKINS' AS FULL_NAME
UNION SELECT ' MRS SUSAN ADAMS' AS FULL_NAME
UNION SELECT ' MS AUGUSTA ADA KING ' AS FULL_NAME
) RAW_DATA
) TEST_DATA
) TITLE
) FIRST_NAME
Es difícil responder sin saber cómo se formatea el “nombre completo”.
Podría ser “Apellido, Primer Nombre Segundo Nombre” o “Primer Nombre Segundo Nombre Apellido”, etc.
Básicamente tendrás que usar el SUBCADENA función
SUBSTRING ( expression , start , length )
Y probablemente el CARÍNDICE función
CHARINDEX (substr, expression)
Para averiguar el inicio y la longitud de cada parte que desea extraer.
Entonces, digamos que el formato es “Nombre Apellido” que podría (no probado … pero debería estar cerca):
SELECT
SUBSTRING(fullname, 1, CHARINDEX(' ', fullname) - 1) AS FirstName,
SUBSTRING(fullname, CHARINDEX(' ', fullname) + 1, len(fullname)) AS LastName
FROM YourTable
Invierta el problema, agregue columnas para contener las piezas individuales y combínelas para obtener el nombre completo.
La razón por la que esta será la mejor La respuesta es que no hay una forma garantizada de saber si una persona se ha registrado como su primer nombre y cuál es su segundo nombre.
Por ejemplo, ¿cómo dividirías esto?
Jan Olav Olsen Heggelien
Este, aunque es ficticio, es un nombre legal en Noruega y podría, pero no tendría que, dividirse así:
First name: Jan Olav
Middle name: Olsen
Last name: Heggelien
o así:
First name: Jan Olav
Last name: Olsen Heggelien
o así:
First name: Jan
Middle name: Olav
Last name: Olsen Heggelien
Me imagino que se pueden encontrar ocurrencias similares en la mayoría de los idiomas.
Entonces, en lugar de intentar interpretar datos que no tienen suficiente información para hacerlo bien, almacene la interpretación correcta y combínela para obtener el nombre completo.