2014-02-14 88 views
31

我有一些数据,我想基于可能存在或不存在的分隔符进行拆分。基于分隔符的T-SQL拆分字符串

示例数据:

John/Smith 
Jane/Doe 
Steve 
Bob/Johnson 

我使用下面的代码拆分此数据为第一和最后一个名字:

SELECT SUBSTRING(myColumn, 1, CHARINDEX('/', myColumn)-1) AS FirstName, 
     SUBSTRING(myColumn, CHARINDEX('/', myColumn) + 1, 1000) AS LastName 
FROM MyTable 

的结果,我想:

FirstName---LastName 
John--------Smith 
Jane--------Doe 
Steve-------NULL 
Bob---------Johnson 

只要所有行都具有预期的分隔符,此代码就可以正常工作,但当行不行时会出错t:

"Invalid length parameter passed to the LEFT or SUBSTRING function." 

如何重新编写此项以正常工作?

回答

42

可能这会帮助你。

SELECT SUBSTRING(myColumn, 1, CASE CHARINDEX('/', myColumn) 
      WHEN 0 
       THEN LEN(myColumn) 
      ELSE CHARINDEX('/', myColumn) - 1 
      END) AS FirstName 
    ,SUBSTRING(myColumn, CASE CHARINDEX('/', myColumn) 
      WHEN 0 
       THEN LEN(myColumn) + 1 
      ELSE CHARINDEX('/', myColumn) + 1 
      END, 1000) AS LastName 
FROM MyTable 
+0

正是我一直在寻找,谢谢! – Whatevo

+0

很棒!谢谢 – Mikel

4

尝试过滤掉包含那些只喜欢用分隔符和工作管柱行:

SELECT SUBSTRING(myColumn, 1, CHARINDEX('/', myColumn)-1) AS FirstName, 
     SUBSTRING(myColumn, CHARINDEX('/', myColumn) + 1, 1000) AS LastName 
FROM MyTable 
WHERE CHARINDEX('/', myColumn) > 0 

或者

SELECT SUBSTRING(myColumn, 1, CHARINDEX('/', myColumn)-1) AS FirstName, 
     SUBSTRING(myColumn, CHARINDEX('/', myColumn) + 1, 1000) AS LastName 
FROM MyTable 
WHERE myColumn LIKE '%/%' 
4
 
SELECT CASE 
     WHEN CHARINDEX('/', myColumn, 0) = 0 
      THEN myColumn 
     ELSE LEFT(myColumn, CHARINDEX('/', myColumn, 0)-1) 
     END AS FirstName 
    ,CASE 
     WHEN CHARINDEX('/', myColumn, 0) = 0 
      THEN '' 
     ELSE RIGHT(myColumn, CHARINDEX('/', REVERSE(myColumn), 0)-1) 
     END AS LastName 
FROM MyTable 
5

对于那些寻找答案脱颖而出的SQL Server 2016使用String_Split功能

如:

DECLARE @tags NVARCHAR(400) = 'clothing,road,,touring,bike' 

SELECT value 
FROM STRING_SPLIT(@tags, ',') 
WHERE RTRIM(value) <> ''; 

参考:https://msdn.microsoft.com/en-nz/library/mt684588.aspx

+0

我不确定这是否会回答问题,也不像上面的CASE声明方法那样有用。 STRING_SPLIT函数将它变成一个已加入的表格。那么如何获得第一名“名”第二名“姓”?使用交叉应用将我的ds变换成多行。将String数据转换为表格是一种很好的方式。像OP一样,我试图将单个列转换为两列。 STRING_SPLIT将其变成两行,并且无法分辨哪一行是“第一”,“第二”,“第三”(除非超出)。但是这变得更加复杂。 – ripvlan