在SQL Server中分割名称字段的查询
问题描述:
我有一个字段[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]作为一个(但我认为一旦第一个问题解决了,其余的将落到位)。
我觉得我失去了一些明显的东西,但这是一个尝试,搜索和没有解决方案的早晨。提前感谢您花时间查看和回复。
答
使用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 |
+----------+-----------+------------+
答
我相信我有这个工作正常。基本上,我根据名称中是否有空格使用了两个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
什么版本的SQL Server?较新的函数有一些您可能在此使用的新函数(例如,2016年为STRING_SPLIT)。你可能不会在这里获得“全部捕捉”功能。如果该人的姓是两个字怎么办?名字?如果两个词都是两个字呢?如果有一个撇号怎么办?或者是Jr? –
@Jacob H:SQL Server版本是2008R2。我欣赏并理解你的担忧。不幸的是,这个查询并不能解决名称存储设计不佳的问题。目标仅仅是提取相应的最后/第一/中间名,我可以看到是否有任何异常并处理它们。 – RiSt
只是想指出,SqlZim的答案确实处理了双字姓氏问题(我在数据中发现了类似的情况)。只要姓氏的所有部分仅用空格分开,该解决方案就可以工作。 – RiSt