【问题标题】:Splitting the full name in Prefix, First Name, Middle Name and Last Name in SQL Server在 SQL Server 中拆分前缀、名字、中间名和姓氏中的全名
【发布时间】:2021-09-28 02:13:09
【问题描述】:

我正在尝试使用 SQL Server 将全名拆分为 PrefixFirst NameMiddle NameLast Name

我尝试了以下方法,但由于所需的输出不正确,因此无法正常工作。

代码

SELECT TOP 10 
    ID,
    FullName,
    SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName)) AS Full_Name,
    SUBSTRING(FullName, 1, CHARINDEX(' ', FullName)) AS Prefix,
    SUBSTRING(FullName, CHARINDEX(' ', FullName), LEN(FullName) - CHARINDEX(' ', REVERSE(FullName)) - CHARINDEX(' ', FullName) + 1) FirstName,
    RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1) AS Last_Name,
    LEN(SUBSTRING(FullName, CHARINDEX(' ', FullName), LEN(FullName) - CHARINDEX(' ', REVERSE([FullName)) - CHARINDEX(' ', FullName) + 1)) AS FirstNameChar
FROM
    Names WITH (NOLOCK)
WHERE
    (FullName LIKE 'Mr %' OR 
     FullName LIKE 'Mrs %' OR  
     FullName LIKE 'Miss %' OR  
     FullName LIKE 'Ms %' OR
     FullName LIKE 'Dr %')

当前输出:

ID FullName Prefix FirstName Last_Name FirstNameChar
123456 Mr s t Fenech Mr s t Fenech 4

需要的输出:

ID FullName Prefix FirstName Middle_Name Last_Name FirstNameChar
123456 Mr s t Fenech Mr s t Fenech 1

我想删除名字和姓氏之前的空格,可以看到 FirstNameChar 是 4 而实际上应该是 1 并且还能够拆分中间名。

有人可以帮忙吗?

参考stackoverflow上的问题: SQL- Get the substring after first space and second space in separate columns

SQL: parse the first, middle and last name from a fullname field

Parse Prefix First Middle Last Suffix from full name

【问题讨论】:

  • 简单的答案是,你不知道。 Falsehoods Programmers Believe About Names这个问题已经被问过很多次了,事实是,除非你问这个人他们的名字是怎么分开的,否则你总是会弄错的。
  • 停止使用nolock 溅出你的代码

标签: sql-server parsing substring charindex


【解决方案1】:

如果您确实知道名称的格式始终相同(例如, [prefix][space][first][space][middle][space][last] ),您可以执行以下操作:

SELECT SUBSTRING('Mr s t Fenech', CHARINDEX(' ', 'Mr s t Fenech') + 1, LEN('Mr s t Fenech')) AS Full_Name
, REVERSE(PARSENAME(REPLACE(REVERSE('Mr s t Fenech'), ' ', '.'), 1)) AS Prefix
, REVERSE(PARSENAME(REPLACE(REVERSE('Mr s t Fenech'), ' ', '.'), 2)) AS FirstName
, REVERSE(PARSENAME(REPLACE(REVERSE('Mr s t Fenech'), ' ', '.'), 3)) AS MiddleName
, REVERSE(PARSENAME(REPLACE(REVERSE('Mr s t Fenech'), ' ', '.'), 4)) AS LastName
, LEN(REVERSE(PARSENAME(REPLACE(REVERSE('Mr s t Fenech'), ' ', '.'), 1))) AS PrefixLen
, LEN(REVERSE(PARSENAME(REPLACE(REVERSE('Mr s t Fenech'), ' ', '.'), 2))) AS FirstNameLen
, LEN(REVERSE(PARSENAME(REPLACE(REVERSE('Mr s t Fenech'), ' ', '.'), 3))) AS MiddleNameLen
, LEN(REVERSE(PARSENAME(REPLACE(REVERSE('Mr s t Fenech'), ' ', '.'), 4))) AS LastNameLen

但是将'Mr s t Fenech' 替换为FullName

【讨论】:

  • 试试安德鲁劳埃德韦伯勋爵,你会错误地将他的中间名定义为“劳埃德”,将他的姓氏定义为“韦伯”。
  • “就像我说的那样:”?
  • @Larnu 就像我说的:> 如果您确实知道名称的格式始终相同。 . . Ms Jamie Lynn Marie Spears 是另一个不能正常工作的。说,“简单的答案是,你没有,”因为存在异常值,就像说不要编写任何代码,因为某些东西会破坏你的代码。为了澄清,我编辑了我的答案。
【解决方案2】:

此查询适用于所有组合。由于带有空格的前缀是强制性的,因此可以检查带有前缀的 (first_name) 或 (first_name & last_name) 或 (first_name & middle_name & last_name)。

    SELECT TOP 10
     ID
     , FullName
     , SUBSTRING(FullName, 1, CHARINDEX(' ', FullName) - 1) Prefix
     , CASE WHEN CHARINDEX(' ', FullName) = 0 
               THEN NULL
            ELSE SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, (CASE WHEN CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) = 0 
                                                                      THEN LEN(FullName)
                                                                   ELSE CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) - 1
                                                              END)) 
       END FirstName
     , CASE WHEN CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) + 1 + CHARINDEX(' ', FullName), LEN(FullName))) = 0
               THEN NULL
            ELSE SUBSTRING(FullName, CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) + 1 + CHARINDEX(' ', FullName), 
               CASE WHEN CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) = 0
                       THEN LEN(FullName)
                    ELSE ((CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) + 1 + CHARINDEX(' ', FullName), LEN(FullName)))) - 1) END)
       END MiddleName
     , CASE WHEN (CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) + 1 + CHARINDEX(' ', FullName), LEN(FullName))) > 0
               OR CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) > 0)
               THEN CASE WHEN CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) + 1 + CHARINDEX(' ', FullName), LEN(FullName))) + 1 + CHARINDEX(' ', FullName) + CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))), LEN(FullName))) = 0
                            THEN RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName)) - 1)
                         ELSE SUBSTRING(FullName, CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) + 1 + CHARINDEX(' ', FullName), LEN(FullName))) + 1 + CHARINDEX(' ', FullName) + CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))), LEN(FullName))
                    END
            ELSE NULL
       END LastName
     , LEN(CASE WHEN CHARINDEX(' ', FullName) = 0 
                     THEN NULL
                  ELSE SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, (CASE WHEN CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) = 0 
                                                                          THEN LEN(FullName)
                                                                       ELSE CHARINDEX(' ', SUBSTRING(FullName, CHARINDEX(' ', FullName) + 1, LEN(FullName))) - 1
                                                                  END)) 
             END) FirstNameChar
FROM dbo.fullNameTest
WHERE
    (FullName LIKE 'Mr %' OR 
     FullName LIKE 'Mrs %' OR  
     FullName LIKE 'Miss %' OR  
     FullName LIKE 'Ms %' OR
     FullName LIKE 'Dr %');

同时检查这个网址https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=b4a02827d400ac4cadad852bbae96c57

【讨论】:

  • 嗨@alphasqrd:请检查我的答案。我想它会满足你的期望。尽管由于名称的形成,很难拆分名称。我在这里处理过几个名字,例如莱昂内尔·梅西先生、范达尔萨夫人、拉拉小姐、德维·谢蒂博士和帕特里克·D-达尔·瓦克·西西林先生。请从上面的 url 检查您将获得表定义的查询,并随时询问是否有任何查询。谢谢
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 1970-01-01
相关资源
最近更新 更多