編輯:***要測試結果自己,使用以下方法來創建你的全名錶,然後運行代碼以創建標題表,然後運行下面的解決方案代碼。結果正是你所要求的。
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
如果這是幫助你解決問題,請接受它作爲回答。 :)
根據你的榜樣,你不僅要拆分標題,首先姓,名稱,你也想清理你的數據。我會建議分開處理它們。顯然,分離「John Smith先生」的相同方法對於「MsCollins」不起作用。 – rwking 2014-09-29 15:56:31