2017-06-13 50 views
0

我有一个字段[Name],我需要在查询中分解成单独的部分。该字段的格式为:在SQL Server中分割名称字段的查询

LastName,FirstName PossibleMiddle

的样本值:

Doe,John Andrew 
Smith,Jane 

目标输出:


[LastName]   [FirstName]   [MiddleName] 
---------------- ----------------  ---------------- 
Doe     John     Andrew 
Smith    Jane 

这里是我已经能够计算出到现在为止的代码:

SELECT 
LEFT([Name], CHARINDEX(',', [Name]) - 1) AS [Last Name], 
SUBSTRING([Name], CHARINDEX(',', [Name]) +1, LEN([Name])) AS [First and Middle Name], 
SUBSTRING([Name], CHARINDEX(',', [Name]) +1, (CHARINDEX(' ', [Name])-1)) AS [First Name] 
FROM t1 

此代码不适合co原因之一:
1.它失败,因为第二个SUBSTRING没有正确制定。它假定总会有一个空间,但如果有中间名,实际上只会有空间。
2.我不希望[First and Middle Name]作为一个(但我认为一旦第一个问题解决了,其余的将落到位)。

我觉得我失去了一些明显的东西,但这是一个尝试,搜索和没有解决方案的早晨。提前感谢您花时间查看和回复。

+3

什么版本的SQL Server?较新的函数有一些您可能在此使用的新函数(例如,2016年为STRING_SPLIT)。你可能不会在这里获得“全部捕捉”功能。如果该人的姓是两个字怎么办?名字?如果两个词都是两个字呢?如果有一个撇号怎么办?或者是Jr? –

+0

@Jacob H:SQL Server版本是2008R2。我欣赏并理解你的担忧。不幸的是,这个查询并不能解决名称存储设计不佳的问题。目标仅仅是提取相应的最后/第一/中间名,我可以看到是否有任何异常并处理它们。 – RiSt

+0

只是想指出,SqlZim的答案确实处理了双字姓氏问题(我在数据中发现了类似的情况)。只要姓氏的所有部分仅用空格分开,该解决方案就可以工作。 – RiSt

回答

0

使用cross apply(),所以我们不必重复功能,遍布于第二部分的地方:

select 
    lastname = left(t.str,charindex(',',t.str)-1) 
    , firstname = left(x.val,charindex(' ',x.val+' ')) 
    , middlename = nullif(right(x.val,len(x.val)-charindex(' ',x.val)),x.val) 
from t 
    cross apply (
    select val = stuff(t.str,1,charindex(',',t.str),'') 
    ) x(val) 

rextester演示:http://rextester.com/TUJNX20615

回报:

+----------+-----------+------------+ 
| lastname | firstname | middlename | 
+----------+-----------+------------+ 
| Doe  | John  | Andrew  | 
| Smith | Jane  | NULL  | 
+----------+-----------+------------+ 

为了延长您的例子包括mononymous个人:

create table t (str varchar(32)) 
insert into t values 
('Doe,John Andrew') 
,('Smith,Jane') 
,('Sting') -- mononymous 

select 
    lastname = left(t.str,charindex(',',t.str+',')-1) 
    , firstname = nullif(left(x.val,charindex(' ',x.val+' ')),t.str) 
    , middlename = nullif(right(x.val,len(x.val)-charindex(' ',x.val)),x.val) 
from t 
    cross apply (
    select val = stuff(t.str,1,charindex(',',t.str),'') 
    ) x(val) 

rextester演示:http://rextester.com/WPZXC58652

回报:

+----------+-----------+------------+ 
| lastname | firstname | middlename | 
+----------+-----------+------------+ 
| Doe  | John  | Andrew  | 
| Smith | Jane  | NULL  | 
| Sting | NULL  | NULL  | 
+----------+-----------+------------+ 
+0

谢谢!这工作。干杯! – RiSt

+0

@RiSt乐意帮忙! – SqlZim

0

我相信我有这个工作正常。基本上,我根据名称中是否有空格使用了两个case语句。

因此,如果名称中有一个空格,那么打破这个名字。如果没有,则采取其余的领域。

DECLARE @NAME VARCHAR(50) 
SET @NAME = 'Smith,Jane' -- 'Smith,Jane Ann' 

SELECT LEFT(@NAME, CHARINDEX(',', @NAME) - 1) AS LastName, 
    CASE 
     WHEN (CHARINDEX(' ', @NAME) = 0) 
      THEN SUBSTRING(@NAME, CHARINDEX(',', @NAME) + 1, 100) 
     ELSE 
      SUBSTRING(@NAME, CHARINDEX(',', @NAME) + 1, CHARINDEX(' ', @NAME) - CHARINDEX(',', @NAME)) 
    END AS FirstName, 
    CASE 
     WHEN (CHARINDEX(' ', @NAME) = 0) 
      THEN '' 
     ELSE 
      SUBSTRING(@NAME, CHARINDEX(' ', @NAME) + 1, 100) 
    END AS MiddleName