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很乐意帮忙!