-- Create table dbo.FullNameTest
IF OBJECT_ID('FullNameTest') IS NOT NULL BEGIN
DROP TABLE dbo.FullNameTest;
END;
CREATE TABLE FullNameTest
(
ID INT Not Null IDENTITY
, FullName NVARCHAR(80) Not Null
, CONSTRAINT PK_ID PRIMARY KEY CLUSTERED(ID)
);
GO
INSERT INTO FullNameTest
VALUES('Mr Hog Finn Gad'), ('Grace Bruce'), ('Dr.Paul'), ('Master Clark James'), ('Mrs.Rignald')
SELECT * FROM FullNameTest
规则
将条目(Mrs,Mr,Miss等)视为标题,并忽略标题后的点
当我们有标题和单个名称时,将其作为标题,姓氏返回
当我们有标题和两个名称将其作为Title,FirstName和LastName
当我们有title和三个名字时,返回Title,FirstName并将其余部分视为LastName
如果我们没有标题,请将数据重新命名为FirstName,LastName
无需任何功能。
所以我们可以用这种形式获得价值:
Title FirstName LastName
------------------------------
Mr Hog Finn Gad
Null Grace Bruce
Dr Null Paul
Master Clark James
Mrs Null Rignald
谢谢
答案 0 :(得分:0)
编辑:***要自己测试结果,请使用以下命令创建全名表,然后运行代码以创建标题表,然后运行下面的解决方案代码。结果正是您所要求的。
CREATE TABLE #FullNameTest
(
ID INT Not Null IDENTITY
, FullName NVARCHAR(80) Not Null
);
GO
INSERT INTO #FullNameTest
VALUES('Mr Hog Finn Gad'), ('Grace Bruce'), ('Dr.Paul'), ('Master Clark James'), ('Mrs.Rignald')
这可能不适用于所有情况,并且需要使用带有标题的参考表,但它应该让您入门。同样,我建议加入一些数据验证限制,这样你就不会得到意想不到的输入。如果不可行,则先运行一些算法来清理数据。当你尝试在SQL中做这样的事情时,它会变得混乱。
创建一个标题参考表,其中包含标题和标题长度。
create table #title (Title varchar(15), Long as len(Title))
insert into #title (Title) values
('Mr'),
('Mister'),
('Ms'),
('Miss'),
('Mrs'),
('Misses'),
('Dr'),
('Doctor'),
('Senator'),
('Officer'),
('Master')
您的表格如下:
Mr 2
Mister 6
Ms 2
Miss 4
Mrs 3
Misses 6
Dr 2
Doctor 6
Senator 7
Officer 7
Master 6
然后你就拥有了这个巨大的代码块,试图解释你可能拥有的每一个输入案例。再次 - 如果可能,请先尝试清理数据。否则,每次收到意外情况时,您都必须修改此代码。
select y.RawName
, y.Title
, y.FName
, case when RawName like '%'+y.Title+'% %'+y.FName+'%' then RIGHT(RawName, len(RawName)-LEN(y.Title+'% %'+y.FName+' ')+1)
when Title is not null then RIGHT(RawName, len(RawName)-len(title))
when Title is null and RawName like '% %' then RIGHT(RawName, len(RawName)-len(Fname)-1)
end LName
from (
select RawName
, Title
, case when right(RawName, len(RawName)-len(title)-1) like '% %'
then left(right(RawName, len(RawName)-len(title)-1), CHARINDEX(' ', right(RawName, len(RawName)-len(title)-1),1))
when RawName like '% %'
then left(RawName, CHARINDEX(' ', RawName, 1))
end FName
from (
select
replace(f.FullName, '.', '') RawName
, t.title Title
, ROW_NUMBER() over(partition by f.fullname order by len(t.title) desc) row_n
from #FullNameTest f
left join #title t
on left(f.fullname, t.long) = t.title
) x
where row_n = 1
) y
根据您上面的示例,您将获得以下内容:
RawName Title FName LName
DrPaul Dr NULL Paul
Grace Bruce NULL Grace Bruce
Master Clark James Master Clark James
Mr Hog Finn Gad Mr Hog Finn Gad
MrsRignald Mrs NULL Rignald
如果这可以帮助您解决问题,请接受它作为答案。 :)
答案 1 :(得分:0)
以下是我最终使用的代码:
SELECT Title,
CASE
WHEN CHARINDEX(' ',PARTNAME) = 0 THEN NULL
ELSE LEFT(PARTNAME, CHARINDEX(' ',PARTNAME))
END AS [FirstName],
CASE WHEN CHARINDEX(' ',PARTNAME) = 0 THEN PARTNAME
ELSE RIGHT(PARTNAME, LEN(PARTNAME) - CHARINDEX(' ', PARTNAME))
END AS [LastName]
FROM
(
SELECT TITLE, LTRIM(REPLACE(REPLACE(FULLNAME,ISNULL(TITLE,''),''),'.','')) AS PARTNAME
FROM (
SELECT CASE
WHEN CHARINDEX('DR ',FullName) = 1 THEN 'Dr'
WHEN CHARINDEX('DR.',FullName) = 1 THEN 'Dr'
WHEN CHARINDEX('MR ',FullName) = 1 THEN 'Mr'
WHEN CHARINDEX('MR.',FullName) = 1 THEN 'Mr'
WHEN CHARINDEX('MRS ',FullName) = 1 THEN 'Mrs'
WHEN CHARINDEX('MRS.',FullName) = 1 THEN 'Mrs'
WHEN CHARINDEX('MISS ',FullName) = 1 THEN 'Miss'
WHEN CHARINDEX('MISS.',FullName) = 1 THEN 'Miss'
WHEN CHARINDEX('MASTER ',FullName) = 1 THEN 'Master'
WHEN CHARINDEX('MASTER.',FullName) = 1 THEN 'Master'
ELSE NULL
END AS [Title], FullName
FROM FullNameTest
) B
) C
非常感谢你的帮助