T-SQL子字符串 - 分隔名字和姓氏

use*_*697 41 t-sql sql-server-2008

我有一个列,其中包含FirstName和LastName.我正在编写一份报告来分隔FirstName和LastName.如何在T-SQL中分离FirstName和LastName?

blu*_*tor 50

假设FirstName所有角色都是第一个空格:

SELECT
  SUBSTRING(username, 1, CHARINDEX(' ', username) - 1) AS FirstName,
  SUBSTRING(username, CHARINDEX(' ', username) + 1, 8000) AS LastName
FROM
  whereever
Run Code Online (Sandbox Code Playgroud)

  • @libjup实际上有很好的理由使用高于任何可能长度的固定值.为什么要费心计算每一行的长度?浪费了周期. (23认同)
  • 您可以使用索引0的情况对此进行改进,以便在它们只有名字时允许. (4认同)
  • 为什么使用点? (2认同)
  • 也许您想使用LEN(username)而不是8000 (2认同)

小智 18

我能找到的最简单的方法是:

SELECT 
  SUBSTRING(FullName, 1, CHARINDEX(' ', FullName) - 1) AS FirstName,
  REVERSE(SUBSTRING(REVERSE(FullName), 1, CHARINDEX(' ', REVERSE(FullName)) - 1)) AS LastName
FROM
  [PERSON_TABLE]
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢这种解决方案,因为它从全名中删除了中间名 (2认同)
  • 这也是我最喜欢的答案。虽然,如果您也希望您的名字也包含中间名(如果考虑到姓氏是一个名词),则可以执行以下操作:`REPLACE(FullName,REVERSE(SUBSTRING(REVERSE(FullName)) ,1,CHARINDEX('',REVERSE(FullName))-1)),'')AS FirstName` (2认同)

Tim*_*ter 14

这应该工作:

Select  
    LTRIM(RTRIM(SUBSTRING(FullName, 0, CHARINDEX(' ', FullName)))) As FirstName
,   LTRIM(RTRIM(SUBSTRING(FullName, CHARINDEX(' ', FullName)+1, 8000)))As LastName
FROM TABLE
Run Code Online (Sandbox Code Playgroud)

编辑:采用Aaron和Jonny的暗示,固定长度为8000,以避免不必要的计算.


小智 7

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
Run Code Online (Sandbox Code Playgroud)


Bri*_*rne 6

这将照顾诸如"Firstname Z. Lastname"和"First Z Last"之类的名字

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]
Run Code Online (Sandbox Code Playgroud)


lib*_*jup 5

如果名字和姓氏之间用空格隔开,则可以执行以下操作:

SELECT SUBSTRING(FirstAndSurnameCol, 0, CHARINDEX(' ', FirstAndSurnameCol)) Firstname,
SUBSTRING(FirstAndSurnameCol, CHARINDEX(' ', FirstAndSurnameCol)+1, LEN(FirstAndSurnameCol)) Surname FROM ...
Run Code Online (Sandbox Code Playgroud)

  • SUBSTRING(FirstAndSurnameCol,CHARINDEX('',FirstAndSurnameCol)+ 1,LEN(FirstAndSurnameCol)) (3认同)

小智 5

这是带有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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

使用:

SELECT dbo.ufn_GetFirstName(Fullname) as FirstName, dbo.ufn_GetLastName(Fullname) as LastName FROM #Names
Run Code Online (Sandbox Code Playgroud)


Nem*_*emo 5

我认为以下查询将有助于从FullName中拆分FirstName和LastName,即使只有FirstName也是如此。例如:' Philip John '可以分为PhilipJohn。但是如果只有Philip,因为Space的charIndex为0,它将仅给您''。

尝试以下之一。

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
Run Code Online (Sandbox Code Playgroud)

希望这会帮助你。:)