Я добавлю ваши примеры в таблицу памяти, чтобы мы могли проверить их, как показано ниже: - (вам это не нужно)
Declare @NameTable table (fullname varchar(250))
insert into @NameTable values
('LASTNAME,FIRSTNAME MIDDLENAME'),
('LASTNAME,FIRSTNAME,MIDDLENAME'),
('LAST NAME,FIRSTNAME MIDDLENAME'),
('LAST NAME,FIRSTNAME (MIDDLENAME)'),
('LASTNAME,FIRSTNAME (NICKNAME) MIDDLENAME'),
('LASTNAME,FIRSTNAME') -- no middle name
Давайте попробуем разбить его на несколько меньших шагов, сначала получите скобкии затем фамилию и продолжайте, пока мы не получим все части.
;with FindBrackts as (
/* get rid of brackets */
select *,CHARINDEX('(',fullname) bStart,CHARINDEX(')',fullname) bEnd from @NameTable
),RemoveBrackts as (
select case when bStart>0 then substring(fullname,1,bStart-1)+substring(fullname,bEnd+2,len(fullname)-bEnd+1)
else fullname end fullname from FindBrackts)
,LastNameAndTheRest as (
select substring(fullname,1,CHARINDEX(',',fullname)-1) [LASTNAME]
,substring(fullname,CHARINDEX(',',fullname)+1,len(fullname)-CHARINDEX(',',fullname)) [TheRest] from RemoveBrackts
),LastFirstMiddle as (
select [LASTNAME],[TheRest],CHARINDEX(',',replace([TheRest],' ',',')) [mStart] from LastNameAndTheRest
)
select [LASTNAME]
,case when mStart=0 then [TheRest] else substring([TheRest],1,[mStart]-1) end FIRSTNAME
,case when mStart=0 then null else substring([TheRest],[mStart]+1,len([TheRest])-[mStart]) end MIDDLENAME
from LastFirstMiddle
Результат будет примерно таким, как показано ниже: -
LASTNAME FIRSTNAME MIDDLENAME
======== ========= ==========
LASTNAME FIRSTNAME MIDDLENAME
LASTNAME FIRSTNAME MIDDLENAME
LAST NAME FIRSTNAME MIDDLENAME
LAST NAME FIRSTNAME NULL
LASTNAME FIRSTNAME MIDDLENAME
Если это поможет, и вы найдетеесли есть больше условий, добавьте их и, возможно, обновите запрос, чтобы учесть их.
здесь то же самое в SQL Fiddle http://sqlfiddle.com/#!18/2dd42/2/0
Или, если вы не хотите использовать CTE, егонемного длиннее, но вы можете попробовать следующее: -
select
SUBSTRING(fullname, 0, CHARINDEX(',', fullname)) AS LastName
,SUBSTRING(replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','),1,CHARINDEX(',',replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','))-1) [FirstName]
,SUBSTRING(fullname,2+len(fullname)-CHARINDEX(',',reverse(replace(fullname,' ',','))),len(fullname)) MiddleName
from @NameTable
Результаты будут такими, как показано ниже (немного отличается от предыдущего решения)
LastName FirstName MiddleName
======== ========= ==========
LASTNAME FIRSTNAME MIDDLENAME
LASTNAME FIRSTNAME MIDDLENAME
LAST NAME FIRSTNAME MIDDLENAME
LAST NAME FIRSTNAME (MIDDLENAME)
LASTNAME FIRSTNAME MIDDLENAME
, если нет MiddlenameCTE справится с этим, но для выбора потребуется обновить следующее: -
select
SUBSTRING(fullname, 0, CHARINDEX(',', fullname)) AS LastName
,case when CHARINDEX(',',replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','))>0 then
SUBSTRING(replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','),1,CHARINDEX(',',replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','))-1)
else replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',',') end [FirstName]
,case when CHARINDEX(',',replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','))>0 then
SUBSTRING(fullname,2+len(fullname)-CHARINDEX(',',reverse(replace(fullname,' ',','))),len(fullname))
else NULL end MiddleName
from @NameTable
Это немного длинно и может быть написано короче.в любом случае результаты будут такими, как показано ниже: -
LastName FirstName MiddleName
========= ========= ==========
LASTNAME FIRSTNAME MIDDLENAME
LASTNAME FIRSTNAME MIDDLENAME
LAST NAME FIRSTNAME MIDDLENAME
LAST NAME FIRSTNAME (MIDDLENAME)
LASTNAME FIRSTNAME MIDDLENAME
LASTNAME FIRSTNAME NULL