Sql server 用于在SQL Server中拆分名称字段的查询

Sql server 用于在SQL Server中拆分名称字段的查询,sql-server,Sql Server,我有一个字段[名称],我需要在查询中将其分解为单独的部分。该字段的格式为: LastName,可能是FirstName middle 样本值: Doe,John Andrew Smith,Jane 产出目标: [LastName] [FirstName] [MiddleName] ---------------- ---------------- ---------------- Doe John

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

LastName,可能是FirstName middle

样本值:

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
此代码不正确,原因如下:
1.它失败是因为第二个子字符串的公式不正确。它假定总是有一个空格,但实际上只有在有中间名的情况下才有空格。
2.我不希望[名字和中间名]成为一个整体(但我认为,一旦第一个问题得到解决,其余的问题就会解决)


我觉得我错过了一些显而易见的东西,但这是一个漫长的上午,我一直在尝试,寻找,还没有找到解决办法。提前感谢您抽出时间查看和回复。

我相信我的操作是正确的。基本上,我使用了两个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
使用
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演示:

返回:

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

要将您的示例扩展到包含同名个体,请执行以下操作:

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演示:

返回:

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

什么版本的SQL Server?较新的版本有一些新的功能,您可以在这里使用(例如2016年的STRING_SPLIT)。你可能不会在这里得到一个“一网打尽”的函数。如果这个人的姓是两个字呢?名字?如果两者都是两个词呢?如果一个人有撇号怎么办?还是Jr?@Jacob H:SQL Server版本是2008R2。我理解你的担忧。不幸的是,此查询无法修复名称以设计糟糕的方式存储的事实。我们的目标只是提取各自的姓/名/中间名,我可以看看我们是否有任何异常并处理它们。我只是想指出,SqlZim的答案确实处理了两个字的姓问题(我在数据中发现了类似的情况)。只要姓氏的所有部分都用空格隔开,这个解决方案就行了。@RiSt很乐意帮忙!