如何将完整名称拆分为TSQL中的名字,中间名,姓氏和后缀

时间:2016-11-15 21:21:54

标签: sql tsql sql-server-2012

对于例如 我在表中有一个FullName列

|FirstName | Middle Name | lastName | Suffix |
|--------------------------------------------|
|Smith     | NULL        | Johns    | Null   |
|James     | NULL        | Macoy    | Null   |
|Krushit   | J           | Patel    | II     |
|Sheldon   | NULL        | Devid    | Null   |
|Jeff      | Null        | vandorf  |Jr      |
|Steve     |Smith        | Ronder   |I       |

我想结果像

C:\Users\YourUserNameHere\AppData\Roaming\Sublime Text 3\Packages\TypeScript\typescript\commands\error_info.py

2 个答案:

答案 0 :(得分:0)

正如其他人所评论的那样,这个问题太模糊了(问题描述得太复杂了),无法提供特别有用的答案,但无论如何我都会尝试。

如果我们对您想要拆分的名称值做出一些假设,我们可以提出解决方案:

  • 每个名称包含2到4个单词",每个单词用一个空格分隔
  • 形成2个单词名称:[First Name] [Last Name]
  • 形成3个单词名称:[First Name] [Last Name] [Suffix]
  • 形成4个单词名称:[First Name] [Middle Name] [Last Name] [Suffix]

在这种情况下,我们可以解决如下问题(如果我们的名字存在于一个名为names的表中,并且有一个名为Name的列:

SELECT      
 SUBSTRING(Name, 1, CHARINDEX(' ', Name) - 1) AS FirstName
,CASE LEN(Name) - LEN(REPLACE(Name, ' ', '')) + 1
    WHEN 2 THEN NULL
    WHEN 3 THEN NULL
    WHEN 4 THEN SUBSTRING(RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name)), 1, CHARINDEX(' ', RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name))) - 1)
 END AS [Middle Name]
,CASE LEN(Name) - LEN(REPLACE(Name, ' ', '')) + 1
    WHEN 2 THEN RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name))
    WHEN 3 THEN SUBSTRING(RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name)), 1, CHARINDEX(' ', RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name))) - 1)
    WHEN 4 THEN SUBSTRING(RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name, CHARINDEX(' ', Name) + 1)), 1, CHARINDEX(' ', RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name, CHARINDEX(' ', Name) + 1))) - 1)
 END AS lastName
,CASE LEN(Name) - LEN(REPLACE(Name, ' ', '')) + 1
    WHEN 2 THEN NULL
    WHEN 3 THEN REVERSE(SUBSTRING(REVERSE(Name), 1, CHARINDEX(' ', REVERSE(Name)) - 1))
    WHEN 4 THEN REVERSE(SUBSTRING(REVERSE(Name), 1, CHARINDEX(' ', REVERSE(Name)) - 1))
 END AS Suffix
FROM names

这不是最优雅的解决方案,但它说明了CHARINDEXSUBSTRING的用法,可用于分解这样的字符串。肯定有一些冗余可以通过这个查询和更优雅的方式来实现它(加上它可能不适合你的数据集,因为上面的假设),但希望它对你来说是一个有用的起点。

一个更简洁的解决方案可能是创建一个带2个参数的函数 - 一个字符串和一个整数来表示哪个" word"你希望从那个字符串返回。然后,您可以在类似的CASE逻辑中调用此函数,以根据需要返回名称中的第一个,第二个,第三个或第四个单词。

如果你需要能够处理[First Name] [Middle Name] [Last Name]形式的3个单词名称(我怀疑你这样做),你可能想要建立一个可能的后缀列表并使用该列表来确定每个3个单词的名称是否都有相应的后缀或中间名。

答案 1 :(得分:0)

SELECT 

d.First_Name


,CASE WHEN 0 = CHARINDEX(' ',d.REST_OF_NAME)
       THEN NULL  
       ELSE SUBSTRING(                                                    ---- finds the middle name from rest of the name 
                       d.REST_OF_NAME
                      ,1
                      ,CHARINDEX(' ',d.REST_OF_NAME)-1
                     )
       END AS Middle_Name

,SUBSTRING(
             d.REST_OF_NAME                                             ---- finds the Last name from rest of the name 
            ,1 + CHARINDEX(' ', d.REST_OF_NAME)
            ,LEN( d.REST_OF_NAME)
           ) AS Last_Name

,d.Suffix
,d.CUSTOMER_NUMBER
,D.Orignal_Data_String
from
(SELECT c.Suffix,

CASE WHEN 0 = CHARINDEX(' ',c.Remainding_Name_Part)
         THEN c.Remainding_Name_Part 
         ELSE SUBSTRING(                                                    ---- substring first name fro rest of the name from reminding part of the name 
                         c.Remainding_Name_Part
                        ,1
                        ,CHARINDEX(' ',c.Remainding_Name_Part)-1
                       )
    END AS First_Name
,CASE WHEN 0 = CHARINDEX(' ',c.Remainding_Name_Part)  
         THEN NULL  
         ELSE SUBSTRING(
                         c.Remainding_Name_Part
                        ,CHARINDEX(' ',c.Remainding_Name_Part)+1           ------    substring rest of the name after substracting firstname from the remainding partof the name
                        ,LEN(c.Remainding_Name_Part)
                       )
    END AS REST_OF_NAME

,c.CUSTOMER_NUMBER
,C.Orignal_Data_String
FROM 
(SELECT 
CASE WHEN RIGHT(b.Name,2) IN ('IV','Jr','Sr')
     THEN LTRIM(RTRIM(RIGHT(b.Name,2)))                                     ----finds suffix in name        
        WHEN RIGHT(b.Name,3) IN ('III','Esq',' II')
       THEN LTRIM(RTRIM(RIGHT(b.Name,3))) 

ELSE NULL
END AS [Suffix]
,
CASE WHEN RIGHT(b.Name,2) IN ('IV','Jr','Sr')
     THEN LTRIM(RTRIM(LEFT(b.name,LEN(b.name)-2)))                         ----finds remider part of name after subtrecting suffix        
       WHEN RIGHT(b.Name,3) IN ('III',' Esq',' II')
       THEN LTRIM(RTRIM(LEFT(b.name,LEN(b.name)-3)))

ELSE LTRIM(RTRIM(b.name))
END AS [Remainding_Name_Part]
,B.CUSTOMER_NUMBER
,B.Orignal_Data_String


FROM 

(SELECT 
REPLACE(REPLACE(LTRIM(RTRIM(a.NAME)),'  ',' '),'  ',' ') AS [Name]         ------ Clears spaces 
,A.NAME AS [Orignal_Data_String]
,a.CUSTOMER_NUMBER
FROM 
(
SELECT NAME,CUSTOMER_NUMBER                                                 ------ finds the customers
FROM [FIS_CORE_FEEDS_DM].[dbo].[FIS_DAILY_CUST_TABLE]
WHERE CUSTOMER_TYPE !='O'
        )A
     )B
   )C
)D