2014-09-26 60 views
-1

我在我的数据库中有一列存储标题,名字和姓氏。但是这个列中的数据有时并不干净,客户的标题缺失或为空,其他时候名字不可用,而在其他时间,姓氏无效。现在,我想要将列分隔或拆分为三个 - 标题,名字,姓氏,记住我必须检查空值或空数据。如何清理这个数据让喜欢错误:不返回SUBSTRING和CHARINDEX分隔列中的值

Msg 536, Level 16, State 2, Line 1 
Invalid length parameter passed to the RIGHT function. 

Msg 537, Level 16, State 2, Line 1 
Invalid length parameter passed to the LEFT or SUBSTRING function. 

我写了这样的脚本,但不够好。

SELECT FullName 
    , LEFT(FullName, ISNULL(NULLIF(CHARINDEX(' ', FullName) - 1, -1), LEN(FullName))) AS Title 
    , RIGHT(Salute, LEN(Salute) - CHARINDEX(' ', FullName, 1)) FirstName 
    , SUBSTRING(FullName, 1, CHARINDEX(' ', FullName, 19) - 1) LastName 
FROM Details 

如果我们有一个标题和一个名字,我们应该分成Title,FirstName。如果没有标题,我们会将其视为姓名和姓氏 谢谢。

+0

空数据不能存在于字符串中。那么一些数据看起来像什么代表你的每个案例。你在这里的模式匹配水平之后。如果Title和firstName缺失,你怎么知道这是姓氏而不是名字?它是否被一个像COMMA这样的值分开了?所以它可能看起来像,史密斯先生或史密斯先生,或者你可以有史密斯先生,在这种情况下,我不知道史密斯是最后名字还是名字? – xQbert 2014-09-26 15:25:21

+0

没有COMMA或类似的东西。数据不带分隔符输入。 – dLight 2014-09-26 15:32:15

+0

所以你用空格来表示分离,然后假设名字或标题不像Jake II或John Paul Jones先生那样复杂。 – xQbert 2014-09-26 15:35:07

回答

1

不是我最好的作品,但近看:

http://sqlfiddle.com/#!3/f87e8/18/0根据注释中标识的规则似乎工作。如果规则发生变化,应该是在案例中移动现有代码以满足需求。

Select FullName, 
CASE len(fullname) - len(replace(fullName,' ','')) 
WHEN 2 then 
    LEFT(FULLNAME,charIndex(' ',FULLNAME)) 
WHEN 1 then 
    '' 
when 0 then 
    '' 
end as Title, 

CASE len(fullname) - len(replace(fullName,' ','')) 
WHEN 2 then 
    REPLACE(REPLACE(FULLNAME,LEFT(FULLNAME,charIndex(' ',FULLNAME)),''),REVERSE(LEFT(REVERSE(FULLNAME),CHARINDEX(' ', REVERSE(FullName)))),'') 
WHEN 1 then 
    LEFT(FULLNAME,CHARINDEX(' ', FullName)) 
when 0 then 
    '' 
end as First, 

CASE len(fullname) - len(replace(fullName,' ','')) 
WHEN 2 then 
     REVERSE(LEFT(REVERSE(FULLNAME),CHARINDEX(' ', REVERSE(FullName)))) 
When 1 then 
     REVERSE(LEFT(REVERSE(FULLNAME),CHARINDEX(' ', REVERSE(FullName)))) 
WHEN 0 then 
     FullName 
end as LAST 
from foo 
+0

美丽!这工作得很好。谢谢xQbert – dLight 2014-09-29 08:29:59

0

采取在这个

RIGHT(Salute, LEN(Salute) - CHARINDEX(' ', FullName, 1)) FirstName 

你能看到如何

CHARINDEX(' ', FullName, 1)

可能是超出范围的礼炮

set nocount on;   
declare @fullname char(200) = 'jonnywalker whiskey  '; 
declare @left int; 
set @left = (select ISNULL(NULLIF(CHARINDEX(' ', @fullname) - 1, -1), LEN(@fullname))); 
select @left; 
select LEFT(@fullname, @left) AS Title 

declare @salute char(200) = 'salute  '; 
declare @right int; 
set @right = (select (LEN(@salute) - CHARINDEX(' ', @fullname, 1))); 
select @right; 
select RIGHT(@salute, @right) FirstName; 
+0

谢谢。但上述查询给出了一个错误: 消息536,级别16,状态2,行23 传递给RIGHT函数的长度参数无效。 – dLight 2014-09-29 08:22:18

+0

@dLight确实如此。它会告诉你错误在哪里。你看不到你能否看到CHARINDEX('',FullName,1)可能超出Salute的范围? – Paparazzi 2014-09-29 12:48:32