我有一个客户名单,其名称是全名。 我想创建一个以全名作为参数并分别返回名字和姓氏的函数。如果这不可能,我可以有两个单独的函数,一个返回名字,另一个返回姓氏。全名列表包含最多三个单词的名称。 我想要的是: -
示例: -
**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
我搜索并找到了无法按预期工作的解决方案,并希望得到一些建议。
答案 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中。或者,更好的是,修复数据源,以便从一开始就记录正确的名字和姓氏。
在这里演示:
答案 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
这是输出..
答案 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