我们有一列名称,由于要以LASTNAME FIRSTNAME MIDDLENAME
的形式出现,因此需要解析多个内容。该列始终以LASTNAME
开头,然后以逗号分隔为FIRSTNAME
,然后对于()
,可以将其用逗号分隔或空格分隔,甚至用括号分隔(MIDDLENAME
)。
我有用于过滤LASTNAME
的代码:
SUBSTRING([Name], 0, PATINDEX('%,%', [Name])) AS LastName
但是我无法通过FIRSTNAME
和MIDDLENAME
进行过滤。这是列的外观示例
LASTNAME,FIRSTNAME MIDDLENAME LASTNAME,FIRSTNAME,MIDDLENAME LAST NAME,FIRSTNAME MIDDLENAME LAST NAME,FIRSTNAME (MIDDLENAME)
现在,如果括号中有内容,我们不想在括号中显示该信息。因此我们将忽略MIDDLENAME
。该列可以包含LASTNAME
,FIRSTNAME
和MIDDLENAME
的任意组合,并带有空格或逗号或方括号,并且MIDDLENAME
也可以存在于方括号之外:
LASTNAME,FIRSTNAME (NICKNAME) MIDDLENAME
在这种情况下,我们希望MIDDLENAME
并忽略NICKNAME
非常感谢您的帮助!
答案 0 :(得分:1)
我会将您的示例添加到内存表中,以便我们可以对其进行如下测试:-(您不需要这样做)
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
如果没有中间名,则CTE将对其进行处理,但是需要将选择内容更新为以下内容:-
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
答案 1 :(得分:0)
Please try this:
;WITH Data AS (
SELECT a.ID,a.LastName
,REPLACE(REPLACE(REPLACE(REPLACE(a.RotN,' (','.'),')',''),',','.'),' ','.') AS [DotSplitName]
FROM (
SELECT ROW_NUMBER()OVER(ORDER BY (SELECT 1)) AS [ID]
,SUBSTRING(t.fullname,1,CHARINDEX(',',t.fullname)-1) AS [LastName]
,SUBSTRING(t.fullname,CHARINDEX(',',t.fullname)+1,999) AS [RotN] /*Rest of the name*/
FROM @NameTable t
WHERE t.fullname LIKE '%[,]%'
) a
)
SELECT d.ID,d.LastName
,COALESCE(PARSENAME(d.DotSplitName,3),PARSENAME(d.DotSplitName,2)) AS [FirstName]
,PARSENAME(d.DotSplitName,1) AS [MiddleName]
,CASE WHEN PARSENAME(d.DotSplitName,3) IS NOT NULL THEN PARSENAME(d.DotSplitName,2) ELSE NULL END AS [NickName]
FROM Data d
;
Thank you Ali Al-Mosawi for Memory table example