【问题标题】:sql - how to split fullname into first and last namesql - 如何将全名拆分为名字和姓氏
【发布时间】:2017-01-04 11:05:38
【问题描述】:

如果我有一个包含全名的列的表,例如:

fullname
------------
Joe Bloggs
Peter Smith
Mary Jones and Liz Stone

如何使用 SQL 重试全名列中每个条目的名字和姓氏。在我的示例中,我并不担心第三个条目中的第二个名字,即 Liz Stone。

所以基本上是检索

Firstname
---------
Joe
Peter
Mary

Lastname  
--------
Bloggs 
Smith
Jones

【问题讨论】:

  • 您使用的是什么版本的 SQL Server?
  • 中间名呢,比如John Phillips Souza?除非您确定每个名字都只包含一个名字和姓氏,否则这个问题可能会很困难。
  • 不需要中间名:)
  • Sql Server 2016 引入了 STRING_SPLIT 方法。
  • 为什么用Jones 和Stone 而不是Jones、and、Liz、Stone?对于简单的名字、姓氏,拆分字符串是可以原谅的。在这种情况下,虽然看起来你有一些严重的问题,多个人存储在同一行中

标签: tsql


【解决方案1】:

这是一个 SQL Server 2016 之前的方法,它使用基本的字符串函数来隔离名字和姓氏。

SELECT SUBSTRING(fullname, 1, CHARINDEX(' ', fullname) - 1) AS Firstname,     
       SUBSTRING(fullname,
                 CHARINDEX(' ', fullname) + 1,
                 LEN(fullname) - CHARINDEX(' ', fullname)) AS Lastname
FROM yourTable

请注意,此解决方案假定 fullname 列仅包含一个名字和一个姓氏(即没有中间名、首字母等)。

【讨论】:

  • 名字出来没问题,但姓氏也包括合作伙伴的名字,例如“琼斯和莉兹·斯通”
  • 将and 行分成两条记录可能需要一个自定义函数。如果您确实有这种边缘情况,我建议您在将数据导入 SQL Server 之前对其进行清理。
  • 我们可以用您姓氏 sql 中的空白字符串替换“AND”及其后面的任何名称吗?
  • 我们能不能只用 sql 部分中的空白字符串替换“AND”以及它后面的任何名称,您是否推断出姓氏?
【解决方案2】:

这是一个滑坡,没有简单的答案。也就是说,请考虑以下内容

Declare @YourTable table (FullName varchar(50))
Insert Into @YourTable values
('Joe Bloggs'),
('Peter Smith'),
('Betty Jane Martinez'),
('Mary Jones and Liz Stone')


Select A.*
      ,FirstName = Pos1+case when Pos3 is not null then ' '+Pos2 else '' end
      ,LastName  = case when Pos3 is null then Pos2 else Pos3 end
 From @YourTable A
 Cross Apply (
    Select Pos1 = xDim.value('/x[1]','varchar(max)')
          ,Pos2 = xDim.value('/x[2]','varchar(max)')
          ,Pos3 = xDim.value('/x[3]','varchar(max)')
          ,Pos4 = xDim.value('/x[4]','varchar(max)')
          ,Pos5 = xDim.value('/x[5]','varchar(max)')
          ,Pos6 = xDim.value('/x[6]','varchar(max)')
     From  (Select Cast('<x>' + replace((Select substring(FullName,1,charindex(' and ',FullName+' and ')-1) as [*] For XML Path('')),' ','</x><x>')+'</x>' as xml) as xDim) as A 
 ) B

返回

FullName                    FirstName   LastName
Joe Bloggs                  Joe         Bloggs
Peter Smith                 Peter       Smith
Betty Jane Martinez         Betty Jane  Martinez
Mary Jones and Liz Stone    Mary        Jones

如果对视觉有帮助,则 CROSS APPLY 生成

【讨论】:

    【解决方案3】:
    SELECT CASE
               WHEN CHARINDEX(' ', FullName) > 0
               THEN SUBSTRING(FullName, 1, LEN(FullName) - CHARINDEX(' ', REVERSE(FullName)))
               ELSE ''
           END AS FirstName,
           CASE
               WHEN CHARINDEX(' ', FullName) > 0
               THEN REVERSE(SUBSTRING(REVERSE(FullName), 
                           1, 
                           CHARINDEX(' ', REVERSE(FullName)) - 1))
               ELSE FullName
           END AS LastName
    FROM(VALUES('Mary Anne Bloggs'), ('Joe Bloggs'), ('Bloggs')) AS T(FullName);
    

    此版本检查全名中是否有空格进行拆分。如果没有,则将名字设置为空字符串,并将全名放入姓氏中。另外,如果有多个空格,则在最后一个空格上使用 reverse 进行拆分

    【讨论】:

      【解决方案4】:

      BigQuery:标准 Sql

      substr(name,1,STRPOS(name,' ')-1) as FirstName,

      substr(name,STRPOS(name,' ')+1,length(name)) as LastName

      【讨论】:

      【解决方案5】:

      我使用这个查询来检索名字和姓氏

      SELECT SUBSTRING(FULLNAME, 1, CASE WHEN CHARINDEX(' ', FULLNAME)>0 THEN CHARINDEX(' ', FULLNAME) - 1 ELSE LEN(FULLNAME) END ) AS Firstname,
        REVERSE(SUBSTRING(REVERSE(FULLNAME), 1, CASE WHEN CHARINDEX(' ', REVERSE(FULLNAME))>0 THEN CHARINDEX(' ', REVERSE(FULLNAME)) - 1 ELSE LEN(REVERSE(FULLNAME)) END ) )AS Firstname FROM  HRMDESFO.EMPLOID
      

      Resuls

      【讨论】:

      • 如果查询结果是文本,则应将其发布为文本而不是屏幕截图
      • 我注意到名字别名用于两个替换。我可以使用您的查询,但必须更改第二个替换 AS 姓氏的别名
      【解决方案6】:

      在没有任何假设的情况下,这是这个问题的最简单和最短的。您还可以使用rtrim(ltrim('firstname lastname')) 进一步增强此功能。

      以防字符串前有空格,

      Select 
          substring('Firstname Lastname',1,CHARINDEX(' ', 'Firstname Lastname')) as firstname, 
          substring('Firstname Lastname',CHARINDEX(' ', 'Firstname Lastname'),LEN('Firstname Lastname')) as Lastname
      

      【讨论】:

        【解决方案7】:
        select  passemail,substring(passemail,1,instr(passemail,'@') - 1) as name ,
        substring(passemail,instr(passemail,'@') + 1,length(passemail)) from passenger
        

        【讨论】:

        • 请在您的答案中添加解释以帮助其他人学习。仅代码答案被认为是不礼貌的。
        【解决方案8】:

        获取名字

        SELECT SUBSTR(FULLNAME,1,(LOCATE(' ',FULLNAME)))  AS FIRSTTNAME from EmployeeDetails;
        

        为姓氏

        SELECT SUBSTR(FULLNAME,(LOCATE(' ',FULLNAME)))  AS LASTNAME from EmployeeDetails;
        

        所以

        SELECT  SUBSTR(FULLNAME,1,(LOCATE(' ',FULLNAME)))  AS FIRSTTNAME, SUBSTR(FULLNAME,(LOCATE(' ',FULLNAME)))  AS LASTNAME from EmployeeDetails;
        

        【讨论】:

          【解决方案9】:
          SELECT 
            LEFT(column_name,  POSITION(' ' IN column_name)-1)                     AS first_name,
            RIGHT(column_name, LENGTH(column_name) - POSITION(' ' IN column_name)) AS last_name
          FROM table_name
          

          【讨论】:

          • column_name:是包含名称的列。 table_name:是从中选择 column_name 的表的名称
          • 请通过添加描述来更好地格式化您的答案。
          【解决方案10】:

          SELECT SUBSTR(NAME,1,(LOCATE(NAME, ' '))) AS FIRSTTNAME, SUBSTR(NAME,(LOCATE(NAME, ' ')+1)) AS LASTNAME from yourTABLE;

          【讨论】:

            【解决方案11】:

            你可以使用,

             STRING_SPLIT (string , separator)
            

            【讨论】:

            • 这应该是一条评论。如果您想将此作为答案发布,您应该发布一个实际示例。 OP 将如何访问姓氏?
            • 或者在这种情况下也提到了“史密斯先生和简夫人”或“亚历克斯史密斯和爱丽丝简”
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-06-16
            • 1970-01-01
            • 1970-01-01
            • 2014-07-23
            相关资源
            最近更新 更多