将全名拆分为姓氏和姓氏

时间:2017-08-30 11:43:50

标签: sql sql-server tsql

我有一个客户名单,其名称是全名。 我想创建一个以全名作为参数并分别返回名字和姓氏的函数。如果这不可能,我可以有两个单独的函数,一个返回名字,另一个返回姓氏。全名列表包含最多三个单词的名称。 我想要的是: -

  • 当全名由两个单词组成时。第一个应该是 名称和第二个应该是姓氏。
  • 当全名由三个单词组成时。第一个和第二个单词应该是名字,而第三个单词应该是姓氏。

示例: -

**Full Name**    
John Paul White    
Peter Smith    
Ann Marie Brown    
Jack Black    
Sam Olaf Turner

结果: -

**First Name    Last Name**    
John Paul     White    
Peter         Smith      
Ann Marie     Brown    
Jack          Black    
Sam Olaf      Turner

我搜索并找到了无法按预期工作的解决方案,并希望得到一些建议。

7 个答案:

答案 0 :(得分:3)

保持简短

DECLARE @t TABLE(Fullname varchar(40))
INSERT @t VALUES('John Paul White'),('Peter Smith'),('Thomas')

SELECT
  LEFT(Fullname, LEN(Fullname) - CHARINDEX(' ', REVERSE(FullName))) FirstName,
  STUFF(RIGHT(FullName, CHARINDEX(' ', REVERSE(FullName))),1,1,'') LastName
FROM
  @t

结果:

FirstName  LastName
John Paul  White
Peter      Smith
Thomas     NULL

答案 1 :(得分:1)

如果你某些你的名字只会是两个或三个单词,只有一个空格,那么我们可以依靠基本字符串函数来提取名字和姓氏。

SELECT
    CASE WHEN LEN(col) = LEN(REPLACE(col, ' ', '')) + 2
         THEN SUBSTRING(col, 1,
                        CHARINDEX(' ', col, CHARINDEX(' ', col) + 1) - 1)
         ELSE SUBSTRING(col, 1, CHARINDEX(' ', col) - 1)
    END AS first,
    CASE WHEN LEN(col) = LEN(REPLACE(col, ' ', '')) + 2
         THEN SUBSTRING(col,
                        CHARINDEX(' ', col, CHARINDEX(' ', col) + 1) + 1,
                        LEN(col) - CHARINDEX(' ', col, CHARINDEX(' ', col)))
         ELSE SUBSTRING(col,
                        CHARINDEX(' ', col) + 1,
                        LEN(col) - CHARINDEX(' ', col))
    END AS last
FROM yourTable;

哎呀,但似乎有效。我的感觉是你应该在某个时候修复你的数据模型。擦除名称数据的更理想的地方是数据库外部,例如在Java中。或者,更好的是,修复数据源,以便从一开始就记录正确的名字和姓氏。

在这里演示:

Rextester

答案 2 :(得分:0)

你一次尝试做两件事......我不会为你解决问题,但这就是我要采取的方向:&/ p>

1)检查此字符串以进行字符串拆分:https://ole.michelsen.dk/blog/split-string-to-table-using-transact-sql.html。这将允许您将名称解析为临时表,并且您可以在其上执行逻辑以根据您的规则创建名称

2)将其创建为表值函数,以便您可以从参数返回单行解析的FirstName,LastName。这样你就可以加入它并包含在你的结果中

答案 3 :(得分:0)

您是否尝试过使用PARSENAME功能?

将全名拆分为相应的名字和姓氏的最后一种方法是使用PARSENAME字符串函数,如下面的脚本所示:

    DECLARE @FullName VARCHAR(100)
    SET @FullName = 'John White Doe'

    SELECT CONCAT(PARSENAME(REPLACE(@FullName, ' ', '.'), 3),' ',PARSENAME(REPLACE(@FullName, ' ', '.'), 2)) AS [FirstName],
  PARSENAME(REPLACE(@FullName, ' ', '.'), 1) AS [LastName]

有关详情,请转到Site enter image description here

这是输出..

enter image description here

答案 4 :(得分:0)

使其成为表值函数。

请参阅here以获取示例

这是创建函数所需的代码。基本上你只需要拆分 LastName

IF OBJECT_ID(N'dbo.ufnParseName', N'TF') IS NOT NULL
    DROP FUNCTION dbo.ufnParseName;
GO
CREATE FUNCTION dbo.ufnParseName(@FullName VARCHAR(300))
RETURNS @retParseName TABLE 
(
-- Columns returned by the function    
FirstName nvarchar(150) NULL,  
LastName nvarchar(50) NULL
)
AS 
-- Returns the spliced last name.
BEGIN

     DECLARE 
        @FirstName nvarchar(250),
        @LastName nvarchar(250);
    -- Get common contact information

    SELECT @LastName = RTRIM(RIGHT(@FullName, CHARINDEX(' ', REVERSE(@FullName)) - 1));
    SELECT @FirstName = LTRIM(RTRIM(Replace(@FullName, @LastName, '')))

     INSERT @retParseName
        SELECT @FirstName, @LastName;

    RETURN;
END

您可以SELECT * FROM dbo.ufnParseName('M J K');

运行

为什么表值函数

您可以摆脱sql查询的重复并实现DRY

答案 5 :(得分:0)

另一个选项(只是为了好玩)是使用一个小的XML与CROSS APPLY

一起使用

示例

Select FirstName = ltrim(reverse(concat(Pos2,' ',Pos3,' ',Pos4,' ',Pos5)))
      ,LastName  = reverse(Pos1)
 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)')
                From  (Select Cast('<x>' + replace(reverse(A.[Full Name]),' ','</x><x>')+'</x>' as xml) as xDim) XMLData
             ) B

<强>返回

FirstName               LastName
John Paul               White
Peter                   Smith
Ann Marie               Brown
Jack                    Black
Sam Olaf                Turner
                        Cher
Sally Anne Bella Donna  Baxter

答案 6 :(得分:0)

您可以尝试以下查询。它是根据您的要求编写的,它只处理full_name,其中包含2或3个部分。

;WITH cte AS(
    SELECT full_name, (LEN(full_name) - LEN(REPLACE(full_name, ' ', '')) + 1) AS size FROM @temp
    )

SELECT FirstName = 
    CASE 
        WHEN size=3 THEN PARSENAME(REPLACE(full_name, ' ', '.'), 3) + ' ' + PARSENAME(REPLACE(full_name, ' ', '.'), 2)
        ELSE PARSENAME(REPLACE(full_name, ' ', '.'), 2)
    END,
    PARSENAME(REPLACE(full_name, ' ', '.'), 1) AS LastName
FROM cte