将记录拆分为以分隔符分隔的列

时间:2017-07-29 14:33:28

标签: sql sql-server tsql sql-server-2012

我是一个需要帮助的问题。我有一个带有一组字符串的列,用"分隔。" (下面的例子)我通过使用子字符串和charindex来分割它的问题,问题是第二个分隔符并不总是相同的长度所以当我说它没有正确分割时。

Column A
100.11111.12.16
101.36333
101.REMOTE.01
200.ACTIVE

我需要将上述数据拆分为3列。

Column A           Column B      Column C     Column D
100.11111.12.16    100           11111          12.16
101.36333          101           36333  
101.REMOTE.01      101           REMOTE          01
200.ACTIVE         200           ACTIVE

正如你所看到的那样,第二个分隔符并不总是真正落在同一个位置。第一个总是在3之后,所以我可以分开它,但它是第二个我有分裂的问题,因为我无法找到确切的位置。

4 个答案:

答案 0 :(得分:3)

这是使用字符串函数的一种方法

SELECT [Column A] = t.string, 
       [Column B] = LEFT(t.string, Charindex('.', t.string) - 1), 
       [Column C] = Reverse(Parsename(Reverse(cs.string), 1)), 
       [Column D] = Stuff(cs.string, 1, NULLIF(fpos, 0), '') 
FROM   Yourtable t 
       CROSS apply(VALUES (Substring(string, Charindex('.', string) + 1, Len(string))))cs(string) 
       CROSS apply(VALUES (Charindex('.', cs.string))) p (fpos) 

MSDN链接:

答案 1 :(得分:2)

使用与XML CROSS APPLY

一起使用的小XML的另一个选项

示例

Declare @YourTable Table ([Column A] varchar(50))
Insert Into @YourTable Values 
 ('100.11111.12.16')
,('101.36333')
,('101.REMOTE.01')
,('200.ACTIVE')

Select A.* 
      ,[Column B] = B.Pos1
      ,[Column C] = B.Pos2
      ,[Column D] = substring(concat('.'+B.Pos3,'.'+B.Pos4),2,50)
 From  @YourTable A
 Cross Apply (
                Select Pos1 = xDim.value('/x[1]','varchar(max)')
                      ,Pos2 = xDim.value('/x[2]','varchar(max)')
                      ,Pos3 = xDim.value('/x[3]','varchar(max)')
                      ,Pos4 = xDim.value('/x[4]','varchar(max)')
                From  (Select Cast('<x>' + replace(A.[Column A],'.','</x><x>')+'</x>' as xml) as xDim) as X
             ) B

<强>返回

enter image description here

答案 2 :(得分:2)

对于此解决方案,必须了解ISNULL函数。 SUBSTRING,NULLIF,CHARINDEX函数的链接早先由受人尊敬的@Pரதீப்提供。 LEN功能不言自明。

SELECT a [Column A],
  SUBSTRING(a, 1, ISNULL(p1 - 1, LEN(a))) [Column B],
  SUBSTRING(a, p1 + 1, ISNULL(p2, LEN(a) + 1) - p1 - 1) [Column C],
  SUBSTRING(a, p2 + 1, LEN(a) - p2) [Column D]
FROM(VALUES('100.11111.12.16'),
           ('101.36333'),
           ('101.REMOTE.01'),
           ('200.ACTIVE'),
           ('42170')) a(a)
CROSS APPLY(VALUES(NULLIF(CHARINDEX('.', a), 0))) b(p1)
CROSS APPLY(VALUES(NULLIF(CHARINDEX('.', a, p1 + 1), 0))) c(p2)
CROSS APPLY(VALUES(NULLIF(CHARINDEX('.', a, p2 + 1), 0))) d(p3);

rextester.com上查看。

答案 3 :(得分:0)

如果点的最大出现次数为3,那么parsename可以完成所有工作:

select columnA,
       parsename(reverse(columnA),1) columnB,
       parsename(reverse(columnA),2) columnC,
       parsename(reverse(columnA),3) + isnull('.'+parsename(reverse(columnA),4),'')  columnD
from table